|
Mercury Modem
Mercury ARQ/Broadcast modem
|
#include "carousel.h"#include "arq.h"#include "arq_protocol.h"#include "freedv_api.h"#include "modem_mfsk.h"#include <math.h>#include <stdarg.h>#include <stdio.h>#include <string.h>
Macros | |
| #define | FRAME_HDR 2 |
| #define | SEG_HDR 4 |
| #define | CTL_SEG_K1 127 |
| #define | INLINE_CTL (SEG_HDR + CAR_POLL_BYTES) |
| #define | FB_UNSEEN 255 |
| #define | SLOW_RUNG_FRAMES 3 /* round cap on the two slowest rungs */ |
| #define | TURN_QUANTUM_MS 30000 |
| #define | TURN_CAP_MS 45000 |
| #define | MAX_KEYDOWN_MS 30000 /* airtime cap per round */ |
| #define | HEAD_MS (110 + nav_lead(c)) |
| #define | TAIL_MS 200 |
| #define | GUARD_MS ARQ_CHANNEL_GUARD_MS |
| #define | ISS_GUARD_MS ARQ_ISS_POST_ACK_GUARD_MS |
| #define | CHAIN_GAP_MS ARQ_ACK_DATA_GAP_MS /* poll -> first burst, one keydown */ |
| #define | RESEND_RUN 2 /* pieces repeated from the receiver's gap */ |
| #define | WINDOW_MARGIN_MS 1000 /* a round that never came: re-poll after this */ |
| #define | SENSE_MS 1400 /* after keying, the sender is heard by now */ |
| #define | CARRIER_CHECK_MS 250 /* carrier re-checked this often */ |
| #define | SENDER_SILENCE_MS 90000 /* sender heard no poll this long: nudge */ |
| #define | FLOOR_POLL_EVERY 4 |
| #define | FLOOR_DEEP_DB 3.0f |
| #define | FLOOR_POLL_EVERY_DEEP 12 |
| #define | FLOOR_SILENT_MAX 6 |
| #define | FLOOR_LATE_MS 9000 |
| #define | PATTERN_AIR_MS 640 |
| #define | PATTERN_SENSE_EXTRA_MS 2000 |
| #define | FLOOR_ANSWER_MS 4000 |
| #define | FLOOR_SENSE_MS 3000 |
| #define | FLOOR_DELAY_MARGIN_MS 2000 |
| #define | HANDOVER_SOON_MS 5000 |
| #define | BLOCK_CHECK 4 |
| #define | CTL_FLOOR_MARK 0x07 |
| #define | CTL_DEAF_ON_DB (ARQ_SNR_MIN_DATAC15_DB - 0.5f) |
| #define | CTL_DEAF_OFF_DB (ARQ_SNR_MIN_DATAC15_DB + 1.0f) |
| #define | BLOCK_MIN_K 8 |
| #define | BLOCK_AIR_MS 60000 |
| #define | PROBE_UP_DELIVERY 0.5 /* the best must deliver this well to probe above it */ |
| #define | PROBE_EVERY 8 /* polls before a measured rung is re-probed... */ |
| #define | DEAD_PROBE_MS 60000 /* a dead rung is re-probed after this... */ |
| #define | DEAD_PROBE_MAX_MS 480000 /* ...doubling to at most this */ |
| #define | LV_DECAY 0.8 /* per measured round: memory of ~5 frames */ |
| #define | DEAD_RUN 4 /* consecutive frames lost, none delivered: dead */ |
| #define | DEAD_P 0.02 |
| #define | SNR_GATE_DB 3.0f |
| #define | ROUND_OVERHEAD_MS (4400 + GUARD_MS + ISS_GUARD_MS + HEAD_MS + TAIL_MS) |
| #define | FLOOR_OVERHEAD_MS (PATTERN_AIR_MS + GUARD_MS + ISS_GUARD_MS + HEAD_MS + TAIL_MS) |
| #define | PROVEN_FRAMES 2.0 |
| #define | TG_MS ISS_GUARD_MS /* S's slot opens this long after the end */ |
| #define | TURN_G_MS GUARD_MS /* M's guard either side of a slot */ |
| #define | D_OFDM_MS 1000 /* the latest S decodes an M keydown: OFDM, */ |
| #define | D_MFSK_MS 4500 /* MFSK (on air ~3.7 s after the unkey), */ |
| #define | D_PAT_MS 800 /* a pattern (detected ~0.24 s after it) */ |
| #define | LEAD_MAX_MS (110 + 300) /* tx delay and head silence, with a margin */ |
| #define | K_FLOOR 2 /* continuations of a floor stream */ |
| #define | K_ABOVE 0 /* ...above the floor none: M re-polls */ |
| #define | S_FALLBACK_MS 90000 |
| #define | IDLE_POLL_MIN_MS 3000 |
| #define | IDLE_POLL_MAX_MS 60000 /* doubling up to this */ |
| #define | APP_GRACE_MS 1000 |
| #define | OFFER_RECENT_MS 120000 |
| #define | DATAC3_START_MARGIN_DB 2.0f |
| #define | PAT_MIN_MS (110 + PATTERN_AIR_MS) |
Enumerations | |
| enum | { M_DATA , M_POLL , M_REQ , M_STATUS } |
| enum | { KD_NONE , KD_POLL , KD_ROUND , KD_PATTERN_ACK , KD_PATTERN_BREAK , KD_REQ , KD_DONE , KD_BOTH } |
| enum | { PH_IDLE , PH_SEND , PH_RECV } |
| enum | { MS_WAIT , MS_PLAN , MS_IDLE } |
| enum | { ANC_POLL , ANC_DONE , ANC_ROUND , ANC_REQ , ANC_PATTERN , ANC_BOTH } |
Functions | |
| void | car_set_nav_ms (uint32_t ms) |
| void | car_set_nav_below_db (float db) |
| void | car_set_nav_loss (double loss) |
| bool | car_wants_nav (const car_t *c) |
| static uint32_t | nav_lead (const car_t *c) |
| static uint32_t | burst_gap_ms (int lv) |
| int | car_level_mode (int level) |
| static bool | has_data (const car_t *c) |
| static bool | peer_direction_done (const car_t *c) |
| bool | car_is_idle (const car_t *c) |
| size_t | car_tx_inflight (const car_t *c) |
| const char * | car_failed (const car_t *c) |
| int | car_overruns (const car_t *c) |
| static uint64_t | mslot_lo (const car_t *c, const car_mlog_t *l, int i) |
| static uint64_t | mslot_hi (const car_t *c, const car_mlog_t *l, int i) |
| bool | car_slot_reserved (const car_t *m, uint64_t start, uint64_t end) |
| static uint32_t | crc32_step (uint32_t crc, const uint8_t *p, size_t n) |
| static int | piece_of (const car_t *c) |
| static uint32_t | block_check (const car_t *c, uint8_t id, int K, const uint8_t(*piece)[CAR_PIECE], int n) |
| static int | level_of_mode (int mode) |
| static int | mode_payload (int mode) |
| static uint64_t | mode_air (int mode) |
| static uint64_t | level_air (int lv) |
| static bool | ctl_on_floor (const car_t *c) |
| static bool | peer_ctl_on_floor (const car_t *c) |
| static int | pieces_per_frame (const car_t *c, int lv) |
| static bool | inline_ok (int lv) |
| static bool | inline_poll (const car_t *c) |
| static uint64_t | round_air (int lv, int n) |
| static int | keydown_cap (int lv) |
| static int | round_n (const car_t *c) |
| static bool | both_ok (const car_t *c, int lv) |
| static bool | offer_both (car_t *c, uint64_t now) |
| static uint64_t | turn_quantum (int lv) |
| static uint64_t | turn_cap (int lv) |
| static void | encode_ctl (const msg_t *m, uint8_t *b) |
| static void | put_ctl (const car_t *c, car_frame_t *f, const msg_t *m) |
| static bool | decode_ctl (const uint8_t *b, size_t len, msg_t *m) |
| static bool | decode_data (const uint8_t *b, size_t len, msg_t *m, int P) |
| static void | put_seg_hdr (uint8_t *p, const car_sblock_t *s, int count, int first, int P) |
| static uint8_t | resolve16 (uint8_t base, int v4) |
| static void | car_trace (const car_t *c, const char *fmt,...) |
| static void | arm (car_t *c, int t, uint64_t at) |
| uint64_t | car_next_deadline (const car_t *c) |
| static bool | peer_keyed (car_t *c, uint64_t now) |
| static bool | defer_if_busy (car_t *c, int t, uint64_t now) |
| static void | keydown (car_t *c, car_frame_t *fr, int n) |
| static void | bind_rx (car_t *c, int lv) |
| static bool | unopened (const car_t *c) |
| static int | block_k_for (const car_t *c, int lv) |
| static void | open_block (car_t *c, int max_k) |
| static void | piece_bytes (const car_sblock_t *s, int idx, uint8_t *out, int P) |
| static void | apply_need (car_t *c, const msg_t *m) |
| static int | build_round (car_t *c, int lv, int n, uint32_t poll_id, car_frame_t *fr, int reserve0) |
| static double | level_rate (const car_t *c, int lv) |
| static float | level_min_db (int lv) |
| static bool | level_marginal (const car_t *c, int lv) |
| static double | level_delivery (const car_t *c, int lv) |
| static bool | level_dead (const car_t *c, int lv) |
| static void | measure_level (car_t *c, int lv, int frames, double loss, uint64_t now) |
| static bool | level_gated (const car_t *c, int lv) |
| static bool | level_allowed (const car_t *c, int lv) |
| static bool | reprobe_due (const car_t *c, int lv, uint64_t now) |
| static uint64_t | round_overhead (const car_t *c, int lv) |
| void | car_rung_geometry (int lv, bool floor_patterns, int *bytes_per_frame, int *frames, uint64_t *round_air_ms, uint64_t *overhead_ms) |
| static double | air_fraction (const car_t *c, int lv, int frames) |
| static int | level_earned (const car_t *c, int lv) |
| static double | level_goodput (const car_t *c, int lv) |
| static double | level_potential (const car_t *c, int lv) |
| static int | probe_every (const car_t *c, int lv) |
| static int | cap_level (const car_t *c, int lv) |
| static int | choose_level (const car_t *c, uint64_t now) |
| static int | peer_outstanding (const car_t *c) |
| static int | poll_size (const car_t *c, int lv, uint64_t now) |
| static void | decode_block (car_t *c, car_rblock_t *r) |
| static void | deliver_in_order (car_t *c) |
| static void | fill_poll (car_t *c, msg_t *m) |
| static void | take_pieces (car_t *c, const msg_t *m) |
| static uint32_t | ctl_air_max (const car_t *c) |
| static uint32_t | s_ctl_for (const car_t *c, bool deaf) |
| static uint32_t | s_ctl_ms (const car_t *c) |
| static uint32_t | s_round_ms (int lv, int n) |
| static uint32_t | s_pat_ms (void) |
| static uint32_t | r_cap_ms (void) |
| static uint32_t | d_of_mode (int mode) |
| static uint32_t | slot_period (const car_t *c, uint32_t d, uint32_t r) |
| static uint32_t | r_floor_ms (void) |
| static void | m_log_add (car_t *c, uint64_t e) |
| static uint64_t | m_free_from (const car_t *c, uint64_t s, uint64_t len) |
| static void | m_close_from (car_t *c, int j, int i) |
| static void | m_close_slot (car_t *c, uint64_t te, int mk, bool pat, int slot) |
| static int | send_poll_ex (car_t *c, int lv, int n, uint8_t id, bool with_round) |
| static void | send_poll (car_t *c, int lv, int n, uint8_t id) |
| static void | send_pattern (car_t *c, int kind) |
| static void | send_status (car_t *c, uint8_t id) |
| static bool | send_round (car_t *c, uint8_t id) |
| static void | send_req (car_t *c, uint8_t id) |
| static bool | tx_on_pattern (car_t *c, int kind) |
| static int | floor_poll_every (const car_t *c) |
| static void | rx_trace (car_t *c) |
| static void | rx_measure (car_t *c, int lv, uint64_t now) |
| static int | rx_next (car_t *c, uint64_t now, int *plv, int *pn) |
| static void | rx_frame (car_t *c, const msg_t *m, int lv, bool counts) |
| static void | m_enter (car_t *c, int phase, uint64_t now) |
| static void | m_plan (car_t *c, int kind, int lv, int n) |
| static uint64_t | kind_len (const car_t *c, int kind) |
| static uint64_t | plan_len (const car_t *c) |
| static void | m_note (car_t *c, int kind, uint32_t r, uint32_t d, int k, uint32_t rp) |
| static uint32_t | my_ctl_d (const car_t *c) |
| static void | m_key_plan (car_t *c) |
| static bool | ack_can_carry (const car_t *c, uint64_t now) |
| static void | m_try (car_t *c, uint64_t now) |
| static void | m_start_recv (car_t *c, uint64_t now) |
| static void | m_decide_idle (car_t *c, uint64_t now) |
| static void | m_decide_send (car_t *c, uint64_t now) |
| static void | m_decide_recv (car_t *c, uint64_t now) |
| static void | m_decide (car_t *c, uint64_t now) |
| static void | m_timer (car_t *c, uint64_t now) |
| static void | m_heard_end (car_t *c, uint64_t te, int mk, bool pat, int slot) |
| static void | m_on_data (car_t *c, uint64_t now, const msg_t *m, int lv) |
| static void | m_on_ctl (car_t *c, uint64_t now, const msg_t *m) |
| static void | s_anchor (car_t *c, int kind, uint8_t mk, uint64_t eh, uint32_t d, int k, uint32_t rp) |
| static void | s_heard_m (car_t *c, uint64_t now) |
| static void | s_answer (car_t *c, uint64_t now, bool req) |
| static void | s_answer_both (car_t *c, uint64_t now) |
| static void | s_slot (car_t *c, uint64_t now) |
| static void | s_on_data (car_t *c, uint64_t now, const msg_t *m, int lv) |
| static void | s_on_ctl (car_t *c, uint64_t now, const msg_t *m, int mode) |
| int | car_start_level (float snr_db) |
| void | car_init (car_t *c, const car_io_t *io, int rx_level, int tx_level) |
| int | car_max_level_for_bw (int bw_hz) |
| void | car_set_max_level (car_t *c, int lv) |
| int | car_piece_for_start (int caller_start_level) |
| int | car_piece (const car_t *c) |
| int | car_ui_tx_mode (const car_t *c) |
| int | car_ui_rx_mode (const car_t *c) |
| int | car_ui_peer_mode (const car_t *c) |
| void | car_start_sender (car_t *c, uint64_t now) |
| void | car_start_receiver (car_t *c, uint64_t now) |
| static void | note_peer_ctl_deaf (car_t *c, bool deaf) |
| bool | car_peer_ctl_deaf (const car_t *c) |
| void | car_seed_ctl_deaf (car_t *c, bool mine, bool peers) |
| void | car_on_frame (car_t *c, uint64_t now, const uint8_t *bytes, size_t len, int mode, bool control, float snr_db, uint32_t age_ms) |
| void | car_on_tx_done (car_t *c, uint64_t now) |
| static bool | pattern_in_time (const car_t *c, uint64_t now) |
| void | car_on_pattern (car_t *c, uint64_t now, int kind) |
| bool | car_expect_pattern (const car_t *c) |
| void | car_on_app_data (car_t *c, uint64_t now) |
| void | car_on_time (car_t *c, uint64_t now) |
| uint64_t | car_drain_budget_ms (const car_t *c) |
| bool | car_is_master (const car_t *c) |
| uint64_t | car_free_at (const car_t *c, uint64_t now, uint64_t len) |
| void | car_log_ctl (car_t *c, uint64_t end, uint32_t tg) |
| void | car_request_end (car_t *c) |
Variables | ||
| static uint32_t | g_nav_ms | |
| static float | g_nav_below_db = 99.0f | |
| static double | g_nav_loss = 0.3 | |
| static const int | LADDER [CAR_NLEVELS] | |
| struct { | ||
| int mode | ||
| float min_db | ||
| } | START [] | |
| struct { | ||
| int bw_hz | ||
| int top_mode | ||
| } | BW_TOP [] | |
| #define APP_GRACE_MS 1000 |
| #define BLOCK_AIR_MS 60000 |
| #define BLOCK_CHECK 4 |
| #define BLOCK_MIN_K 8 |
| #define CARRIER_CHECK_MS 250 /* carrier re-checked this often */ |
| #define CHAIN_GAP_MS ARQ_ACK_DATA_GAP_MS /* poll -> first burst, one keydown */ |
| #define CTL_DEAF_OFF_DB (ARQ_SNR_MIN_DATAC15_DB + 1.0f) |
| #define CTL_DEAF_ON_DB (ARQ_SNR_MIN_DATAC15_DB - 0.5f) |
| #define CTL_FLOOR_MARK 0x07 |
| #define CTL_SEG_K1 127 |
| #define D_MFSK_MS 4500 /* MFSK (on air ~3.7 s after the unkey), */ |
| #define D_OFDM_MS 1000 /* the latest S decodes an M keydown: OFDM, */ |
| #define D_PAT_MS 800 /* a pattern (detected ~0.24 s after it) */ |
| #define DATAC3_START_MARGIN_DB 2.0f |
| #define DEAD_P 0.02 |
| #define DEAD_PROBE_MAX_MS 480000 /* ...doubling to at most this */ |
| #define DEAD_PROBE_MS 60000 /* a dead rung is re-probed after this... */ |
| #define DEAD_RUN 4 /* consecutive frames lost, none delivered: dead */ |
| #define FB_UNSEEN 255 |
| #define FLOOR_ANSWER_MS 4000 |
| #define FLOOR_DEEP_DB 3.0f |
| #define FLOOR_DELAY_MARGIN_MS 2000 |
| #define FLOOR_LATE_MS 9000 |
| #define FLOOR_OVERHEAD_MS (PATTERN_AIR_MS + GUARD_MS + ISS_GUARD_MS + HEAD_MS + TAIL_MS) |
| #define FLOOR_POLL_EVERY 4 |
| #define FLOOR_POLL_EVERY_DEEP 12 |
| #define FLOOR_SENSE_MS 3000 |
| #define FLOOR_SILENT_MAX 6 |
| #define FRAME_HDR 2 |
| #define GUARD_MS ARQ_CHANNEL_GUARD_MS |
| #define HANDOVER_SOON_MS 5000 |
| #define HEAD_MS (110 + nav_lead(c)) |
| #define IDLE_POLL_MAX_MS 60000 /* doubling up to this */ |
| #define IDLE_POLL_MIN_MS 3000 |
| #define INLINE_CTL (SEG_HDR + CAR_POLL_BYTES) |
| #define ISS_GUARD_MS ARQ_ISS_POST_ACK_GUARD_MS |
| #define K_ABOVE 0 /* ...above the floor none: M re-polls */ |
| #define K_FLOOR 2 /* continuations of a floor stream */ |
| #define LEAD_MAX_MS (110 + 300) /* tx delay and head silence, with a margin */ |
| #define LV_DECAY 0.8 /* per measured round: memory of ~5 frames */ |
| #define MAX_KEYDOWN_MS 30000 /* airtime cap per round */ |
| #define OFFER_RECENT_MS 120000 |
| #define PAT_MIN_MS (110 + PATTERN_AIR_MS) |
| #define PATTERN_AIR_MS 640 |
| #define PATTERN_SENSE_EXTRA_MS 2000 |
| #define PROBE_EVERY 8 /* polls before a measured rung is re-probed... */ |
| #define PROBE_UP_DELIVERY 0.5 /* the best must deliver this well to probe above it */ |
| #define PROVEN_FRAMES 2.0 |
| #define RESEND_RUN 2 /* pieces repeated from the receiver's gap */ |
| #define ROUND_OVERHEAD_MS (4400 + GUARD_MS + ISS_GUARD_MS + HEAD_MS + TAIL_MS) |
| #define S_FALLBACK_MS 90000 |
| #define SEG_HDR 4 |
| #define SENDER_SILENCE_MS 90000 /* sender heard no poll this long: nudge */ |
| #define SENSE_MS 1400 /* after keying, the sender is heard by now */ |
| #define SLOW_RUNG_FRAMES 3 /* round cap on the two slowest rungs */ |
| #define SNR_GATE_DB 3.0f |
| #define TAIL_MS 200 |
| #define TG_MS ISS_GUARD_MS /* S's slot opens this long after the end */ |
| #define TURN_CAP_MS 45000 |
| #define TURN_G_MS GUARD_MS /* M's guard either side of a slot */ |
| #define TURN_QUANTUM_MS 30000 |
| #define WINDOW_MARGIN_MS 1000 /* a round that never came: re-poll after this */ |
| anonymous enum |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
| uint64_t car_drain_budget_ms | ( | const car_t * | c | ) |
| bool car_expect_pattern | ( | const car_t * | c | ) |
| const char * car_failed | ( | const car_t * | c | ) |
| uint64_t car_free_at | ( | const car_t * | c, |
| uint64_t | now, | ||
| uint64_t | len | ||
| ) |
| bool car_is_idle | ( | const car_t * | c | ) |
| bool car_is_master | ( | const car_t * | c | ) |
| int car_level_mode | ( | int | level | ) |
| void car_log_ctl | ( | car_t * | c, |
| uint64_t | end, | ||
| uint32_t | tg | ||
| ) |
| int car_max_level_for_bw | ( | int | bw_hz | ) |
| uint64_t car_next_deadline | ( | const car_t * | c | ) |
| void car_on_app_data | ( | car_t * | c, |
| uint64_t | now | ||
| ) |
| void car_on_frame | ( | car_t * | c, |
| uint64_t | now, | ||
| const uint8_t * | bytes, | ||
| size_t | len, | ||
| int | mode, | ||
| bool | control, | ||
| float | snr_db, | ||
| uint32_t | age_ms | ||
| ) |
| void car_on_pattern | ( | car_t * | c, |
| uint64_t | now, | ||
| int | kind | ||
| ) |
| void car_on_time | ( | car_t * | c, |
| uint64_t | now | ||
| ) |
| void car_on_tx_done | ( | car_t * | c, |
| uint64_t | now | ||
| ) |
| int car_overruns | ( | const car_t * | c | ) |
| bool car_peer_ctl_deaf | ( | const car_t * | c | ) |
| int car_piece | ( | const car_t * | c | ) |
| int car_piece_for_start | ( | int | caller_start_level | ) |
| void car_request_end | ( | car_t * | c | ) |
| void car_rung_geometry | ( | int | lv, |
| bool | floor_patterns, | ||
| int * | bytes_per_frame, | ||
| int * | frames, | ||
| uint64_t * | round_air_ms, | ||
| uint64_t * | overhead_ms | ||
| ) |
| void car_seed_ctl_deaf | ( | car_t * | c, |
| bool | mine, | ||
| bool | peers | ||
| ) |
| void car_set_max_level | ( | car_t * | c, |
| int | lv | ||
| ) |
| void car_set_nav_below_db | ( | float | db | ) |
| void car_set_nav_loss | ( | double | loss | ) |
| void car_set_nav_ms | ( | uint32_t | ms | ) |
| bool car_slot_reserved | ( | const car_t * | m, |
| uint64_t | start, | ||
| uint64_t | end | ||
| ) |
| int car_start_level | ( | float | snr_db | ) |
| void car_start_receiver | ( | car_t * | c, |
| uint64_t | now | ||
| ) |
| void car_start_sender | ( | car_t * | c, |
| uint64_t | now | ||
| ) |
|
static |
| size_t car_tx_inflight | ( | const car_t * | c | ) |
| int car_ui_peer_mode | ( | const car_t * | c | ) |
| int car_ui_rx_mode | ( | const car_t * | c | ) |
| int car_ui_tx_mode | ( | const car_t * | c | ) |
| bool car_wants_nav | ( | const car_t * | c | ) |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
| int bw_hz |
| const struct { ... } BW_TOP[] |
|
static |
|
static |
|
static |
|
static |
| float min_db |
| int mode |
| const struct { ... } START[] |
| int top_mode |