# FSQ Fast Public Technical Specification **Document status:** Public interoperability specification **Specification version:** 1.0-draft **Publication date:** 19 August 2026 **Protocol family:** FSQ / FSQ Fast **Reference implementation:** OpenJSQ **Reference implementation examined:** `jgoddard2/OpenJSQ`, branch `claude/ui-wave-2`, commit family headed by `a5f6d828cc3587e1fbcef14f3eae6a93f9e20b58` **Protocol author / maintainer:** Jerome Goddard II, W4IJG **Purpose:** Public documentation of the technical characteristics of FSQ Fast for interoperability, independent decoding, experimentation, and amateur-radio transparency. --- ## 1. Purpose of this publication FSQ Fast is an extension of the published FSQ waveform that increases throughput by scaling both the symbol rate and the tone spacing by the same integer factor. This document publicly describes the technical characteristics necessary to: - identify an FSQ Fast transmission; - reproduce the transmitted waveform; - recover FSQ Fast symbols from received audio; - decode the FSQ varicode character stream; - distinguish the currently published OpenJSQ FSQ Fast operating profiles; - understand the optional and required integrity suffix used by OpenJSQ; - implement an independent interoperable modem without access to OpenJSQ source code. The intent is that **no secret waveform parameter, unpublished codebook, proprietary scrambling sequence, encryption key, or undisclosed decoder behavior is required to interpret an FSQ Fast transmission**. ### 1.1 Regulatory purpose In the United States, 47 CFR §97.309(a)(4) permits qualifying amateur RTTY/data operation using a technique whose technical characteristics have been documented publicly. This document is intended to provide that public technical documentation for FSQ Fast. This document is technical documentation, not legal advice or a determination that every FSQ Fast transmission is authorized on every amateur band. Operators remain responsible for all applicable amateur-radio rules, including: - authorized emission types and band segments; - the digital-code provisions of 47 CFR §97.309; - the emission standards of 47 CFR §97.307; - authorized or necessary bandwidth; - station identification; - power limits; - good amateur practice; - avoidance of harmful interference. The publication requirement and the authorization to use a particular emission on a particular frequency are separate questions. --- ## 2. Scope This specification defines the **single-carrier FSQ Fast physical and character-coding technique** used by OpenJSQ. It covers: 1. the 33-tone audio-frequency waveform; 2. IFK+ differential tone encoding; 3. base FSQ symbol rates; 4. the FSQ Fast integer multiplier `k`; 5. tone frequencies and symbol timing; 6. the complete FSQ varicode alphabet used by OpenJSQ; 7. transmission start/reference behavior; 8. current registered OpenJSQ FSQ operating profiles; 9. legacy FSQ framing relevant to ordinary directed messages; 10. OpenJSQ's logical CRC-16 suffix; 11. independent transmitter and receiver algorithms; 12. interoperability and mode-selection rules; 13. example test vectors. It does **not** define the JSQ application/service protocol itself. Chat, mail, file transfer, groups, presence, relay, and routing are higher-layer services. FSQ++ and JSQ service records may be transported over FSQ Fast. Their payload formats are documented separately. --- ## 3. Relationship to original FSQ FSQ Fast deliberately preserves the core physical coding of FSQ. The following are unchanged from ordinary FSQ: - 33 physical tones; - differential Incremental Frequency Keying Plus (IFK+) coding; - 32 non-zero differential tone movements; - the FSQ varicode alphabet; - callsign-oriented FSQ/FSQCall framing when that transport is used; - constant-envelope single-tone transmission; - differential reception, which does not require an absolute RF frequency reference. FSQ Fast changes only the **time and frequency scale**. For multiplier `k`: ```text FSQ Fast symbol rate = k × base FSQ symbol rate FSQ Fast tone spacing = k × 8.7890625 Hz ``` Because both quantities scale together, the base profile's spacing-to-symbol-rate ratio remains unchanged. FSQ Fast is therefore best understood as: > **the ordinary FSQ IFK+ waveform executed on a uniformly expanded time/frequency scale.** For `k = 1`, the waveform is ordinary FSQ. For `k > 1`, the waveform is FSQ Fast and is not expected to decode in legacy fldigi/FSQCall implementations unless those implementations add this scaling. --- # Part I — Physical waveform ## 4. Signal type FSQ Fast is a **single-carrier, constant-envelope, phase-continuous, 33-tone differential MFSK/IFK+ waveform**. At any instant during the useful keyed portion of a symbol, exactly one nominal FSQ tone is transmitted. FSQ Fast is **not**: - OFDM; - multiple simultaneous carriers; - a bonded multi-lane mode (OpenJSQ's source contains a multi-lane "Wide" modem, `modem/native/src/wide_fsq_modem.cpp`; no shipping build constructs it, and no bonded waveform is transmitted by this release); - QAM; - PSK; - an encrypted waveform; - a spread-spectrum waveform; - a frequency-hopping system in the regulatory sense of a pseudorandom hopping sequence. The tone changes directly encode the public FSQ symbols. --- ## 5. Tone set There are 33 tone indices: ```text 0, 1, 2, ... , 32 ``` Tone index 16 is the middle tone. Let: ```text fc = configured audio center frequency in Hz k = FSQ Fast multiplier Δf = 8.7890625 × k Hz ``` Then tone `i` is: ```text f(i) = fc + (i - 16) × Δf ``` for: ```text i = 0 ... 32 ``` The OpenJSQ conventional audio center is 1500 Hz unless another center has been selected. ### 5.1 Exact base tone spacing At `k = 1`: ```text Δf = 8.7890625 Hz ``` The exact value is retained rather than the rounded display value 8.8 Hz. ### 5.2 Extreme-tone center span The frequency distance between tone 0 and tone 32 is: ```text Bspan = 32 × Δf = 281.25 × k Hz ``` This is the span between the lowest and highest **tone centers**. It is not, by itself, a regulatory occupied-bandwidth measurement because keyed sidebands extend beyond the outer tone centers. --- ## 6. Base FSQ symbol rates OpenJSQ uses the following exact base symbol rates: | Base profile | Exact symbol rate | |---|---:| | FSQ-2 | 1.953125 Bd | | FSQ-3 | 2.9296875 Bd | | FSQ-4.5 | 3.90625 Bd | | FSQ-6 | 5.859375 Bd | The human-visible names are conventional rounded labels. The corresponding tone-spacing-to-symbol-rate ratios at `k = 1` are: | Base profile | Δf / R | |---|---:| | FSQ-2 | 4.5 | | FSQ-3 | 3.0 | | FSQ-4.5 | 2.25 | | FSQ-6 | 1.5 | --- ## 7. FSQ Fast scaling rule For a selected base profile with exact rate `Rbase`, multiplier `k` is an integer: ```text 1 ≤ k ≤ 7 ``` The effective rate is: ```text R = k × Rbase ``` The tone spacing is: ```text Δf = k × 8.7890625 Hz ``` The symbol duration is: ```text Ts = 1 / R ``` The ratio: ```text Δf / R ``` is therefore exactly the same as for the selected base profile. ### 7.1 What `k` does not change `k` does not change: - the number of tones; - tone numbering; - IFK+ symbol arithmetic; - varicode assignments; - character-table shifts; - message content; - source callsign CRC algorithm; - the meaning of FSQCall command punctuation; - the higher-layer JSQ/FSQ++ service carried by the text stream. --- # Part II — Published operating profiles ## 8. Current OpenJSQ mode registry The following eleven modes are the current published operator-facing OpenJSQ FSQ profiles. The first four are ordinary `k = 1` FSQ profiles. The remaining seven are OpenJSQ FSQ Fast profiles. | Mode | Base | k | Exact rate (Bd) | Exact spacing (Hz) | Extreme-tone span (Hz) | Reference planner BW* | Planning allocation** | Legacy FSQ interop | |---|---|---:|---:|---:|---:|---:|---:|---| | FSQ-2 | FSQ-2 | 1 | 1.953125 | 8.7890625 | 281.25 | 298.04 | 430 Hz | Yes | | FSQ-3 | FSQ-3 | 1 | 2.9296875 | 8.7890625 | 281.25 | 302.04 | 430 Hz | Yes | | FSQ-4.5 | FSQ-4.5 | 1 | 3.90625 | 8.7890625 | 281.25 | 308.04 | 430 Hz | Yes | | FSQ-6 | FSQ-6 | 1 | 5.859375 | 8.7890625 | 281.25 | 314.04 | 430 Hz | Yes | | FSQ-6W | FSQ-3 | 2 | 5.859375 | 17.578125 | 562.50 | 604.08 | 860 Hz | No | | FSQ-12 | FSQ-4.5 | 3 | 11.71875 | 26.3671875 | 843.75 | 924.12 | 1.29 kHz | No | | FSQ-16 | FSQ-4.5 | 4 | 15.625 | 35.15625 | 1125.00 | 1232.16 | 1.72 kHz | No | | FSQ-20 | FSQ-4.5 | 5 | 19.53125 | 43.9453125 | 1406.25 | 1540.20 | 2.15 kHz | No | | FSQ-30 | FSQ-6 | 5 | 29.296875 | 43.9453125 | 1406.25 | 1570.20 | 2.15 kHz | No | | FSQ-36 | FSQ-6 | 6 | 35.15625 | 52.734375 | 1687.50 | 1884.23 | 2.58 kHz | No | | FSQ-42 | FSQ-6 | 7 | 41.015625 | 61.5234375 | 1968.75 | 2198.27 | 3.01 kHz | No | \* **Reference planner BW** is OpenJSQ's engineering estimate used by its slot planner: ```text Bplanner = k × (290.0390625 Hz + 4 × nominal_base_baud) ``` where the nominal base baud values are 2, 3, 4.5, and 6. This is a software channel-planning model, not a laboratory 99% occupied-bandwidth certification. \** **Planning allocation** is a conservative band-plan/channel-spacing reservation of: ```text 430 × k Hz ``` It intentionally includes guard space and is **not** the transmitted occupied bandwidth. Thus the 3.01 kHz FSQ-42 planning allocation must not be mistaken for a statement that the emitted waveform occupies 3.01 kHz. ### 8.1 FSQ-6W FSQ-6W is deliberately: ```text base = FSQ-3 k = 2 ``` It therefore has the same exact symbol rate as ordinary FSQ-6: ```text 5.859375 Bd ``` but twice the tone spacing: ```text 17.578125 Hz ``` The `W` means the signal is wider than ordinary FSQ-6. It does **not** mean the multi-carrier/bonded “Wide” transport. ### 8.2 Registered profiles vs generic combinations The modem mathematics permits a valid base speed to be combined with `k = 1 ... 7`, subject to passband validation. For predictable interoperability, however, software should use one of the registered profiles above unless a new base/`k` combination is explicitly published and agreed by both stations. --- # Part III — IFK+ symbol coding ## 9. Differential symbol values The FSQ physical alphabet contains 32 data symbols: ```text s = 0 ... 31 ``` A data symbol is represented by a **non-zero change** between consecutive tones. Let: ```text Tn = current tone index, 0...32 s = next FSQ symbol, 0...31 ``` Then the next tone is: ```text Tn+1 = (Tn + s + 1) mod 33 ``` The `+1` ensures that no data symbol produces a zero tone movement. ### 9.1 Receiver inverse Given two consecutive decoded tone indices: ```text Tprev Tnext ``` compute: ```text d = (Tnext - Tprev) mod 33 ``` A valid FSQ transition has: ```text d = 1 ... 32 ``` The recovered symbol is: ```text s = d - 1 ``` Thus: ```text s = 0 ... 31 ``` ### 9.2 Differential nature A receiver does not need to know the absolute transmitter frequency perfectly. A constant frequency offset applied to every tone cancels in the differential tone movement. A receiver may therefore adopt the first stable received tone as its differential reference and decode subsequent transitions from relative movement. --- ## 10. Initial reference tone OpenJSQ transmits one unencoded reference tone before the first varicode symbol. The reference tone index is: ```text 16 ``` Therefore its nominal audio frequency is exactly the configured center frequency: ```text f(reference) = fc ``` No data symbol is emitted from the reference tone itself. The first data symbol is encoded by the transition from reference tone 16 to the next tone. Independent receivers SHOULD decode differentially and SHOULD NOT require an exact absolute first-tone frequency as a prerequisite for decoding; the reference implementation's transmitted starting tone is nevertheless specified as tone 16 for exact reproduction. --- # Part IV — Timing, phase, and amplitude ## 11. Symbol timing Every transmitted tone occupies one symbol interval: ```text Ts = 1 / (k × Rbase) ``` Examples: | Mode | Symbol duration | |---|---:| | FSQ-6 | 170.667 ms | | FSQ-6W | 170.667 ms | | FSQ-12 | 85.333 ms | | FSQ-16 | 64.000 ms | | FSQ-20 | 51.200 ms | | FSQ-30 | 34.133 ms | | FSQ-36 | 28.444 ms | | FSQ-42 | 24.381 ms | No inter-symbol silence is required. --- ## 12. Phase continuity The reference implementation uses one continuous oscillator phase accumulator across tone changes. Conceptually: ```text phase[n+1] = phase[n] + 2π fcurrent / Fs sample[n] = A × sin(phase[n]) ``` When a symbol boundary changes the current frequency, the phase accumulator is **not reset**. This produces phase-continuous MFSK/IFK+. An interoperable transmitter SHOULD preserve phase continuity. --- ## 13. Amplitude The useful body of the waveform is constant envelope: one sinusoidal carrier tone at a time. The OpenJSQ reference transmitter uses: ```text normalized peak amplitude = 0.80 ``` The exact normalized audio amplitude is an implementation/interface choice rather than an over-the-air information-bearing parameter. The reference implementation applies approximately: ```text 5 ms attack 5 ms release ``` to the beginning and end of the **entire transmission**. It does not apply a 5 ms amplitude ramp independently at every symbol transition. A compatible implementation may use another sensible overall keying envelope provided it does not alter symbol timing or prevent independent reception. --- # Part V — FSQ varicode ## 14. Varicode grammar Characters are converted into one or two FSQ symbols. ### 14.1 Initial symbols Initial symbols are: ```text 0 ... 28 ``` ### 14.2 Continuation symbols Continuation/table-selector symbols are: ```text 29 = uppercase table 30 = punctuation/digit table 31 = extended table ``` ### 14.3 One-symbol character rule If an initial symbol `0...28` is followed by another initial symbol `0...28`, the first initial is a complete one-symbol character. The second initial begins the next character. ### 14.4 Two-symbol character rule If an initial `0...28` is followed by `29`, `30`, or `31`, the pair selects a character from the corresponding continuation table. --- ## 15. Complete OpenJSQ FSQ character table ### 15.1 Single-symbol table Continuation: none. | First symbol | Character | |---:|---| | 0 | space | | 1 | `a` | | 2 | `b` | | 3 | `c` | | 4 | `d` | | 5 | `e` | | 6 | `f` | | 7 | `g` | | 8 | `h` | | 9 | `i` | | 10 | `j` | | 11 | `k` | | 12 | `l` | | 13 | `m` | | 14 | `n` | | 15 | `o` | | 16 | `p` | | 17 | `q` | | 18 | `r` | | 19 | `s` | | 20 | `t` | | 21 | `u` | | 22 | `v` | | 23 | `w` | | 24 | `x` | | 25 | `y` | | 26 | `z` | | 27 | `.` | | 28 | LF / line feed | ### 15.2 Uppercase table Continuation symbol: ```text 29 ``` | First | Character | First | Character | |---:|---|---:|---| | 0 | `@` | 15 | `O` | | 1 | `A` | 16 | `P` | | 2 | `B` | 17 | `Q` | | 3 | `C` | 18 | `R` | | 4 | `D` | 19 | `S` | | 5 | `E` | 20 | `T` | | 6 | `F` | 21 | `U` | | 7 | `G` | 22 | `V` | | 8 | `H` | 23 | `W` | | 9 | `I` | 24 | `X` | | 10 | `J` | 25 | `Y` | | 11 | `K` | 26 | `Z` | | 12 | `L` | 27 | `,` | | 13 | `M` | 28 | `?` | | 14 | `N` | | | ### 15.3 Punctuation and digit table Continuation symbol: ```text 30 ``` | First | Character | First | Character | |---:|---|---:|---| | 0 | `~` | 15 | `%` | | 1 | `1` | 16 | `&` | | 2 | `2` | 17 | `'` | | 3 | `3` | 18 | `(` | | 4 | `4` | 19 | `)` | | 5 | `5` | 20 | `*` | | 6 | `6` | 21 | `+` | | 7 | `7` | 22 | `-` | | 8 | `8` | 23 | `/` | | 9 | `9` | 24 | `:` | | 10 | `0` | 25 | `;` | | 11 | `!` | 26 | `<` | | 12 | `"` | 27 | `>` | | 13 | `#` | 28 | IDLE | | 14 | `$` | | | The codeword: ```text (28, 30) ``` is IDLE and does not produce a host text character. ### 15.4 Extended table Continuation symbol: ```text 31 ``` | First | Character | |---:|---| | 0 | `=` | | 1 | `[` | | 2 | `\` | | 3 | `]` | | 4 | `^` | | 5 | `_` | | 6 | `{` | | 7 | `|` | | 8 | `}` | | 9 | backtick `` ` `` | | 10 | `±` | | 11 | `÷` | | 12 | `°` | | 13 | `×` | | 14 | `£` | | 15–26 | unassigned | | 27 | BS / backspace, byte `0x08` | | 28 | DEL, byte `0x7F` | --- ## 16. Text normalization in OpenJSQ For exact reproduction of the reference transmitter: - `CR LF` is encoded as one LF codeword; - standalone CR is encoded as LF; - supported listed UTF-8 extended characters are encoded using their table entries; - unsupported Unicode code points are replaced visibly by `?`; - malformed high-byte input is replaced by `?`; - NUL is not an FSQ payload character and is replaced by `?`. These host-normalization rules do not alter the RF symbol grammar. --- # Part VI — Transmission algorithm ## 17. Independent transmitter procedure An independent FSQ Fast transmitter can be implemented as follows. ### Step 1 — Select a profile Determine: ```text base FSQ speed k audio center fc ``` For interoperable public operation, use a registered profile from Section 8. ### Step 2 — Encode text into FSQ varicode symbols Map each character according to Sections 14–16. The result is: ```text s0, s1, s2, ... , sN-1 ``` where every symbol is `0...31`. ### Step 3 — Insert physical reference Initialize: ```text tone = 16 ``` Transmit tone 16 for one symbol interval. ### Step 4 — Convert each symbol to the next tone For each symbol `s`: ```text tone = (tone + s + 1) mod 33 ``` Append the resulting tone to the transmitted sequence. ### Step 5 — Generate each tone frequency For each tone index `tone`: ```text frequency = fc + (tone - 16) × 8.7890625 × k ``` ### Step 6 — Generate phase-continuous audio Transmit each tone for: ```text 1 / (Rbase × k) ``` seconds. Maintain oscillator phase across symbol boundaries. ### Step 7 — End transmission Apply a modest overall release envelope and stop carrier. The physical modem does not require an automatically appended IDLE character. --- ## 18. Transmitter pseudocode ```text function fsq_fast_transmit(text, base_rate, k, fc, sample_rate): spacing = 8.7890625 * k rate = base_rate * k symbol_time = 1 / rate symbols = fsq_varicode_encode(text) tones = [] tone = 16 tones.append(tone) # unencoded reference for s in symbols: tone = (tone + s + 1) mod 33 tones.append(tone) phase = 0 for tone in tones: f = fc + (tone - 16) * spacing for each sample during one symbol_time: output sin(phase) phase = phase + 2*pi*f/sample_rate wrap phase at 2*pi apply only an overall start/end envelope as desired ``` --- # Part VII — Independent receiver ## 19. Minimum independent receiver procedure The OpenJSQ production receiver is more sophisticated than the minimum required for interoperability. Its correlator bank, adaptive receive equalizer, AFC, confidence heuristics, and acquisition state machine are **implementation choices**, not secret on-air protocol fields. An independent receiver need only recover the public tone sequence reliably. ### 19.1 Configure the correct profile The receiver must know: ```text base profile k approximate center frequency ``` FSQ Fast version 1 does not include an in-band mode identifier. ### 19.2 Measure tone plateaus At the configured spacing: ```text Δf = 8.7890625 × k ``` identify successive stable tone indices or relative tone positions. Possible implementations include: - FFT bins; - Goertzel filters; - matched filters; - complex correlators; - filter banks; - maximum-likelihood sequence methods. No particular detector is normative. ### 19.3 Adopt the first tone as reference The first stable tone is the differential reference. A decoder may expect OpenJSQ to transmit tone 16 first, but differential decoding should not depend on perfect absolute tuning. ### 19.4 Decode each transition For each next stable tone: ```text d = (Tnext - Tprev) mod 33 ``` Reject or treat as uncertain a zero movement. Otherwise: ```text s = d - 1 ``` ### 19.5 Decode FSQ varicode Feed recovered symbols to the grammar in Sections 14–15. ### 19.6 Handle end of carrier If one initial varicode symbol `0...28` remains pending at a clean end of carrier, it represents its one-symbol-table character. A receiver should avoid inventing a final character when there is evidence that an additional continuation tone was only partially received. --- ## 20. No mandatory reference receiver algorithm The following OpenJSQ receiver features are deliberately **not** required for FSQ Fast interoperability: - quarter-tone correlator-bank spacing; - exact acquisition dB thresholds; - plateau clustering thresholds; - the adaptive receive emphasis bank; - OpenJSQ's decoder-confidence number; - its SNR estimator; - AFC recenter thresholds; - its internal sample rate; - its event model. These improve reception or host behavior but do not change transmitted information. A third-party implementation may use any receiver that correctly recovers the published tones and symbols. --- # Part VIII — Mode agreement and negotiation ## 21. No automatic Fast-mode identification FSQ Fast does not currently transmit an in-band field that says: ```text "I am FSQ-30" ``` or: ```text "k = 5" ``` Both stations must therefore select the same physical profile before a Fast transmission. A higher-layer protocol may negotiate a faster mode while communicating at a mutually understood baseline mode. For example: ```text station A and B communicate at ordinary FSQ A proposes FSQ-30 B accepts both change to FSQ-30 traffic proceeds at base FSQ-6, k=5 ``` The negotiation mechanism is outside this physical-layer specification. OpenJSQ's is the `K` letter of the compact capability token, carried in the `^` software-version reply and the presence line: `K5` means "I can receive FSQ Fast up to k = 5". It is specified in `JSQ_PUBLIC_PROTOCOL_SPEC.md` §78.2. --- # Part IX — Channel width and spectral use ## 22. Three different width concepts For clarity, this specification uses three different quantities. ### 22.1 Extreme-tone span Exact distance between tone-0 and tone-32 centers: ```text 32 × Δf ``` This contains no allowance for keyed spectral skirts. ### 22.2 Reference planner bandwidth OpenJSQ estimates signal occupancy for slot planning using: ```text Bplanner = k × (290.0390625 + 4 × nominal_base_baud) ``` This is an engineering planner estimate. It is not represented as a laboratory measurement under an FCC occupied-bandwidth measurement procedure. ### 22.3 Channel-planning allocation OpenJSQ additionally recommends a rounded planning reservation: ```text 430 × k Hz ``` This includes guard space intended to separate neighboring planned signals. It is not the width of the emitted modulation. ### 22.4 Operator responsibility Actual necessary/occupied RF bandwidth depends on the generated baseband waveform, radio audio response, transmitter filtering, modulation chain, and measurement definition. The operator is responsible for ensuring the actual RF emission complies with the applicable rules and remains within the permitted band segment. --- ## 23. Reference receiver detector bank is not transmitted bandwidth The OpenJSQ receiver searches frequencies beyond the 33 nominal tones to allow acquisition when a signal is mistuned. Those extra **receiver guard tones do not exist as transmitted information-bearing carriers**. Current reference receiver guard: ```text k = 1...5 : 8 guard-tone spacings on each side k = 6 : 4 guard-tone spacings on each side k = 7 : 3 guard-tone spacings on each side ``` The `k >= 6` guard is derived from an approximately 160 Hz receiver search-margin target, clamped to at least three tones. This detector-bank width must not be confused with the emitted signal bandwidth. --- ## 24. Center-frequency fit At high multipliers, an audio passband may not contain the receiver's full search bank unless the center is close to the middle of the SSB audio channel. For a nominal 300–2700 Hz receive passband, the reference implementation's approximate allowed detector-bank center windows include: | k | Approximate center window | |---:|---| | 4 | 1144–1856 Hz | | 5 | 1355–1645 Hz | | 6 | 1355–1645 Hz | | 7 | 1469–1531 Hz | These are **reference receiver search-bank constraints**, not information-bearing protocol fields. A third-party receiver may have different acquisition margins. --- # Part X — Legacy FSQ framing used over Fast ## 25. Physical modem vs transport framing The FSQ Fast modem converts arbitrary supported FSQ text into tone symbols. It does not itself require that the text be a directed FSQCall frame. OpenJSQ commonly places ordinary FSQ/FSQCall-style frames and FSQ++/JSQ records into that text stream. The following framing is included so an independent implementer can recognize current OpenJSQ directed-message traffic. --- ## 26. Begin- and end-of-transmission text framing OpenJSQ's legacy FSQ transport defines: ```text BOT = SPACE LF ``` that is the two decoded characters: ```text 0x20 0x0A ``` The legacy EOT sequence is: ```text SPACE SPACE BS SPACE SPACE ``` bytes: ```text 0x20 0x20 0x08 0x20 0x20 ``` The physical Fast modem does not create those sequences automatically; the transport supplies them as text. --- ## 27. Directed frame form A current OpenJSQ directed legacy frame is conceptually: ```text BOT : [.] EOT ``` Compactly: ```text " \n" sender ":" hh destination trigger body "." cccc " \b " ``` For OpenJSQ-only FSQ Fast operating profiles, current OpenJSQ requires the logical CRC-16 suffix for directed messages generated through this transport. For interoperable `k = 1` modes, the suffix may be disabled so an unmodified legacy FSQCall receiver does not display it as trailing text. Higher-layer structured FSQ++/JSQ envelopes may use the same physical character stream while defining their own semantic payloads. ### 27.1 Relayed frame form When OpenJSQ retransmits a frame on behalf of another station (the `;` relay request of `JSQ_PUBLIC_PROTOCOL_SPEC.md` §56.2), the retransmitted directed frame has trigger `[` and its body begins with the original author's callsign and a closing bracket: ```text BOT : "[" "]" [.] EOT ``` For example, KK4IB relaying "meet at 7" from N4UZZ to W4IJG sends the decoded text: ```text kk4ib:hh w4ijg[n4uzz]meet at 7 ``` The sender field and its CRC-8 are the RELAY's (the station whose transmitter is on the air). The logical CRC-16 of Section 29 is computed over the relay's callsign, the destination, the trigger `[`, and the body `n4uzz]meet at 7` — the origin marker is part of the body for CRC purposes. A receiver credits the message to the origin inside the brackets and the reception (and any signal reading) to the relay. Implemented in `core/src/fsq_protocol_session.cpp` (transmit) and `core/src/inbound_message_adapt.cpp` (`split_relayed_origin`, receive). ### 27.2 Sounding A sounding is a station identifying itself with no destination, trigger or body: ```text BOT : EOT ``` OpenJSQ transmits one at its configured sounding interval when it has no presence status text to send (`core/src/multi_channel_session.cpp`); with a status text it sends the presence line of `JSQ_PUBLIC_PROTOCOL_SPEC.md` §51.2 instead. A sounding carries no logical CRC-16, because there is nothing after the sender to protect. --- # Part XI — Integrity fields ## 28. Sender callsign CRC-8 The legacy directed-frame header carries a two-hex-digit CRC-8 of the serialized sender callsign. Parameters: ```text width = 8 polynomial = 0x07 init = 0x00 refin = false refout = false xorout = 0x00 ``` Pseudocode: ```text crc = 0 for byte in sender: crc ^= byte repeat 8 times: if crc bit 7 is 1: crc = ((crc << 1) & 0xff) XOR 0x07 else: crc = (crc << 1) & 0xff ``` It is rendered as two hexadecimal characters. This CRC is error detection, not authentication. --- ## 29. OpenJSQ logical message CRC-16 Current OpenJSQ uses CRC-16/CCITT-FALSE to protect the logical fields of a directed message. Parameters: ```text width = 16 polynomial = 0x1021 init = 0xffff refin = false refout = false xorout = 0x0000 ``` The protected byte sequence is: ```text sender 0x00 destination 0x00 trigger 0x00 body ``` No BOT, source CRC text, logical-CRC marker, logical-CRC encoded value, or EOT is included in this CRC calculation. ### 29.1 CRC suffix encoding The 16-bit CRC value is represented by exactly four lowercase base-26 letters. For CRC integer `v`, encode four base-26 digits most-significant first: ```text digit = 0...25 -> 'a'...'z' ``` The encoded value is preceded by: ```text . ``` Therefore the suffix is exactly five FSQ characters: ```text .cccc ``` A decoder should treat a trailing five-character sequence as this CRC suffix only when: 1. the marker and four-letter form are valid; and 2. the decoded CRC matches the reconstructed logical message. Otherwise, in optional legacy mode, those characters may be ordinary message body text. ### 29.2 Integrity is not secrecy Neither CRC-8 nor CRC-16 encrypts or conceals the content. Both algorithms and all protected fields are public. --- # Part XII — Interoperability ## 30. Legacy compatibility The `k = 1` profiles: ```text FSQ-2 FSQ-3 FSQ-4.5 FSQ-6 ``` use ordinary FSQ waveform scaling and are intended to preserve FSQCall/fldigi interoperability, subject to the ordinary application's framing/features. The current Fast profiles: ```text FSQ-6W FSQ-12 FSQ-16 FSQ-20 FSQ-30 FSQ-36 FSQ-42 ``` are OpenJSQ extensions and are not expected to decode with legacy FSQ software that only searches the standard tone spacing/rates. ### 30.1 What a legacy implementation would need to add A conventional FSQ implementation can add Fast support by: 1. exposing the exact base rate; 2. multiplying its symbol rate by `k`; 3. multiplying its tone spacing by the same `k`; 4. retaining the same 33-tone differential arithmetic; 5. retaining the same FSQ varicode; 6. agreeing on the same profile before transmission. No new character codebook is required. --- # Part XIII — Security, transparency, and public decodability ## 31. No encryption or hidden transform FSQ Fast itself contains: - no encryption; - no secret key; - no proprietary interleaver; - no hidden whitening sequence; - no secret FEC matrix; - no unpublished scrambling; - no pseudorandom tone hopping; - no compression required to understand ordinary FSQ text. The waveform can be decoded from this document alone. Higher-layer JSQ/FSQ++ data formats are also intended to be publicly documented. If a station transmits a higher-layer object over FSQ Fast, that object's public specification should be published alongside this physical specification when needed for independent interpretation. --- # Part XIV — Test vectors ## 32. Physical test vector: `test` The lowercase word: ```text test ``` has single-symbol varicode values: ```text t = 20 e = 5 s = 19 t = 20 ``` Therefore: ```text symbols = [20, 5, 19, 20] ``` Starting from reference tone 16: ```text reference = 16 after 20: (16 + 20 + 1) mod 33 = 4 after 5: ( 4 + 5 + 1) mod 33 = 10 after 19: (10 + 19 + 1) mod 33 = 30 after 20: (30 + 20 + 1) mod 33 = 18 ``` The transmitted tone-index sequence is: ```text [16, 4, 10, 30, 18] ``` ### 32.1 FSQ-30 audio frequencies For: ```text mode = FSQ-30 base = FSQ-6 k = 5 fc = 1500 Hz Δf = 43.9453125 Hz R = 29.296875 Bd ``` the sequence is approximately: | Tone index | Audio frequency | |---:|---:| | 16 | 1500.000000 Hz | | 4 | 972.656250 Hz | | 10 | 1236.328125 Hz | | 30 | 2115.234375 Hz | | 18 | 1587.890625 Hz | Each tone lasts approximately: ```text 34.133333 ms ``` before the next symbol boundary. --- ## 33. Varicode test vector: `A?0` Character encoding: ```text A -> [1, 29] ? -> [28, 29] 0 -> [10, 30] ``` Therefore: ```text symbols = [1, 29, 28, 29, 10, 30] ``` A conforming decoder must reconstruct: ```text A?0 ``` --- ## 34. CRC test vector For the logical fields: ```text sender = w4ijg destination = n4uzz trigger = SPACE body = hello ``` the sender CRC-8 defined in Section 28 is: ```text 0xfc ``` The CRC-16/CCITT-FALSE input bytes are: ```text "w4ijg" 00 "n4uzz" 00 " " 00 "hello" ``` The resulting CRC-16 is: ```text 0x5f62 ``` Its four-letter base-26 representation is: ```text bkde ``` and the logical CRC suffix is: ```text .bkde ``` A directed frame using these fields therefore has the conceptual text: ```text BOT + "w4ijg:fc" + "n4uzz" + SPACE + "hello" + ".bkde" + EOT ``` where BOT and EOT are the exact byte sequences in Section 26. --- # Part XV — Reference implementation notes ## 35. Receive implementation used by OpenJSQ The current OpenJSQ native receiver uses, among other techniques: - a full-symbol coherent correlator bank; - quarter-tone search-bin spacing; - plateau tracking; - differential tone-step decoding; - AFC/recentering; - explicit reception-boundary and erasure evidence; - calibrated 3 kHz-reference SNR reporting; - adaptive receive equalization on wider Fast modes. These are reference implementation features. They do not create additional hidden information-bearing fields and are not needed to produce an interoperable transmitter or independent decoder. --- ## 36. Adaptive receive equalization Current OpenJSQ may select receive-only spectral-emphasis candidates on wider Fast modes to compensate for radio-path frequency-response tilt. This processing: - is applied only at the receiver; - is not transmitted; - is not a protocol code; - does not alter the FSQ Fast waveform definition; - does not need to be reproduced by an independent implementation. --- ## 37. Sample rate The digital audio sample rate used inside an implementation is not an over-the-air protocol parameter. OpenJSQ has tested multiple internal rates and presently recommends 48 kHz for its own FSQ receive path because it avoids a known fractional-samples-per-symbol acquisition edge case across the full Fast ladder. A third-party implementation may use another sample rate if it accurately realizes the specified symbol timing and tones. --- # Part XVI — Conformance ## 38. FSQ Fast physical conformance An implementation conforms to this FSQ Fast physical specification if it can transmit and/or decode the following public invariants: 1. 33 tone indices, 0 through 32. 2. Base tone spacing 8.7890625 Hz. 3. Exact base symbol rates listed in Section 6. 4. Integer multiplier `k`, currently 1 through 7. 5. Both rate and spacing scaled by the same `k`. 6. IFK+ transition rule: ```text next = (previous + symbol + 1) mod 33 ``` 7. Symbol alphabet 0 through 31. 8. FSQ varicode grammar and character assignments in Sections 14–15. 9. One initial differential reference tone. 10. Phase-continuous single-tone transmission. 11. No secret transform needed for interpretation. A receiver need not duplicate OpenJSQ's detector implementation. --- ## 39. Profile conformance To claim a named OpenJSQ profile such as `FSQ-30`, an implementation must use the exact base/`k` combination assigned in Section 8. For example: ```text FSQ-30 = base FSQ-6 × k=5 ``` An implementation must not label another combination `FSQ-30` merely because its numeric baud rate is similar. --- ## 40. Fast transport integrity conformance When claiming interoperability with the current OpenJSQ legacy directed-message transport on a Fast profile, an implementation should support: - legacy source CRC-8; - current CRC-16/CCITT-FALSE logical suffix; - validation of the CRC only over the fields listed in Section 29; - base-26 four-letter CRC representation. Application-layer FSQ++ or JSQ objects require their corresponding public higher-layer specifications. --- # Part XVII — Publication and versioning ## 41. Public version identifier This document defines: ```text FSQ Fast Public Technical Specification 1.0-draft ``` The underlying physical algorithm presently has no in-band version field. A future incompatible physical change must therefore: - receive a separately published specification revision; - use a distinguishable operating profile or negotiation mechanism; - not silently reuse an existing profile name for incompatible parameters. --- ## 42. Public availability For regulatory transparency and third-party interoperability, the current revision of this specification should be kept at a stable, publicly accessible location. Recommended publication locations include: - the public OpenJSQ project website; - a public protocol/documentation repository; - a stable release archive. Old published revisions should remain accessible when practical so previously recorded transmissions can still be interpreted. The OpenJSQ source-code license is separate from this public protocol description. Independent software does not need OpenJSQ source code to implement the waveform described here. --- # Appendix A — Quick decoder reference ```text TONES count = 33 indices = 0..32 middle = 16 BASE SPACING 8.7890625 Hz FAST MULTIPLIER k = 1..7 SPACING 8.7890625 * k Hz BASE RATES FSQ-2 1.953125 Bd FSQ-3 2.9296875 Bd FSQ-4.5 3.90625 Bd FSQ-6 5.859375 Bd FAST RATE Rbase * k TONE FREQUENCY fc + (tone - 16) * spacing REFERENCE TONE OpenJSQ TX begins with tone 16 SYMBOL FROM TWO TONES d = (next - previous) mod 33 symbol = d - 1 valid d = 1..32 TONE FROM SYMBOL next = (previous + symbol + 1) mod 33 VARICODE 0..28 = initial 29 = uppercase continuation 30 = punctuation continuation 31 = extended continuation ``` --- # Appendix B — Current registered Fast profiles only ```text FSQ-6W : base FSQ-3 k=2 FSQ-12 : base FSQ-4.5 k=3 FSQ-16 : base FSQ-4.5 k=4 FSQ-20 : base FSQ-4.5 k=5 FSQ-30 : base FSQ-6 k=5 FSQ-36 : base FSQ-6 k=6 FSQ-42 : base FSQ-6 k=7 ``` The older engineering ladder that described every multiplier from an FSQ-6 base (for example FSQ-18 or FSQ-24) is historical design material and is **not** the current OpenJSQ published operator-mode registry. --- # Appendix C — Source and design lineage FSQ Fast is derived from the publicly documented FSQ waveform created by Murray Greenman ZL1BPU and Con Wassilieff ZL2AFP. Important public FSQ references used in the OpenJSQ engineering source ledger include: 1. Murray Greenman ZL1BPU and Con Wassilieff ZL2AFP, **“FSQ — Fast Simple QSO (chat) mode for HF and VHF,”** 6 March 2018. 2. Murray Greenman ZL1BPU, **“FSQ and Error Correction,”** version 0.4, August 2016. 3. Murray Greenman ZL1BPU, **“Synchronous Decoding in WSQCall,”** 22 March 2018. 4. Murray Greenman ZL1BPU, **“Ionospheric Performance of FSQ,”** April 2015. 5. Murray Greenman ZL1BPU and Con Wassilieff ZL2AFP, **“WSQCall.”** 6. David Maddison, **“Digital Radio Modes — Part Two,”** *Silicon Chip*, May 2021, Figure 19. OpenJSQ source documents used to freeze this publication include: ```text modem/native/FSQ_FAST_MODE.md modem/native/SOURCES.md modem/native/src/fsq_modem.cpp modem/native/src/fsq_alphabet.cpp core/include/openfsq/fsq_mode.hpp core/src/fsq_mode.cpp core/src/slot_plan.cpp transports/fsq_legacy/include/openfsq/transport/fsq_legacy/fsq_legacy.hpp transports/fsq_legacy/src/fsq_legacy.cpp docs/PROTOCOL_COMPATIBILITY.md ``` Where historical engineering notes conflict with the current mode registry and source behavior, this specification follows the current shipping mode registry and current transmitter code. --- # Appendix D — U.S. regulatory references This publication was prepared with reference to the current United States amateur-radio rules, particularly: ```text 47 CFR §97.305 — Authorized emission types 47 CFR §97.307 — Emission standards 47 CFR §97.309 — RTTY and data emission codes ``` As of this document's publication date, §97.309(a)(4) refers to techniques whose technical characteristics have been documented publicly. This document is intended to make the FSQ Fast technique publicly understandable and independently implementable. It does not replace the operator's responsibility to determine that a particular emission is authorized on a particular frequency. --- **End of FSQ Fast Public Technical Specification 1.0-draft**