File: README.md

package info (click to toggle)
hydrasdr-host 1.1.0-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 1,436 kB
  • sloc: ansic: 17,644; sh: 26; xml: 23; makefile: 3
file content (300 lines) | stat: -rw-r--r-- 11,417 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
# libhydrasdr

A high-performance Software Defined Radio (SDR) library for HydraSDR devices.

## Overview

libhydrasdr is the core library for interfacing with HydraSDR hardware.

It provides:
- **Device Control**: USB communication, configuration, and streaming
- **Digital Down Converter (DDC)**: High-performance IQ conversion with multiple filter options
- **Streaming Infrastructure**: Lock-free SPSC queues, buffer pools, and triple buffering
- **Cross-Platform Support**: Linux, Windows, macOS, and Android

## DDC Filter Configurations (v1.1.0)

| Config      | Taps | Delay | Rejection | Use Case                    |
|-------------|------|-------|-----------|------------------------------|
| 33_FAST     |  33  |   8   |  ~62 dB   | Low latency, branchless      |
| 47_OPT      |  47  |  12   |  ~63 dB   | Default, Remez equiripple    |
| 65_POW2     |  65  |  16   |  ~66 dB   | Branchless wrap              |
| 83_HIGHPERF |  83  |  21   | >100 dB   | High dynamic range           |

## Streaming Architecture (v1.1.0)

The library uses a high-performance streaming pipeline optimized for low latency and minimal CPU overhead:

```mermaid
flowchart LR
    subgraph USB["USB Callback Thread"]
        UT[USB Transfer]
        RB[Raw Buffer]
    end

    subgraph Consumer["Consumer Thread"]
        SQ[SPSC Queue<br/>16 slots, lock-free]
        DDC[DDC Processing<br/>unpack + filter + decimation]
        TB[Triple Buffer<br/>3 rotating buffers]
        UC[User Callback]
    end

    UT --> RB
    RB -->|"enqueue_swap<br/>(zero-copy)"| SQ
    SQ -->|dequeue| DDC
    DDC --> TB
    TB --> UC
```

### SPSC Queue

Lock-free Single Producer Single Consumer queue for USB → Consumer data transfer:
- **Zero-copy**: Buffer pointers are swapped, not copied
- **Wait-free producer**: USB callback never blocks
- **16 slots**: Absorbs timing jitter between USB and processing

### Triple Buffer

Provides buffer safety for processed sample types (FLOAT32_IQ, INT16_IQ, etc.):
- **3 rotating buffers**: Write, Ready, Read
- **Callback safety**: User callback can hold its buffer while next buffer is processed
- **No blocking**: Producer and consumer never wait for each other

```mermaid
flowchart LR
    W[Write] -->|publish| R[Ready] -->|acquire| RD[Read]
    RD -->|release| W
```

### RAW Mode

For `HYDRASDR_SAMPLE_RAW` and `HYDRASDR_SAMPLE_UINT16_REAL`, data passes directly from the SPSC queue to the callback without triple buffering.
Users requiring buffer persistence should copy the data within the callback.

## DDC Decimation Support (v1.1.0)

The library automatically generates virtual sample rates from hardware rates using cascaded halfband decimation (2x to 64x). This is **transparent** to the application.

**Important**: Always query available sample rates with `hydrasdr_get_samplerates()` - never hardcode values as they are device-specific.

```c
// Query all available rates (device-specific, includes decimated rates)
uint32_t count;
hydrasdr_get_samplerates(dev, &count, 0);
uint32_t *rates = malloc(count * sizeof(uint32_t));
hydrasdr_get_samplerates(dev, rates, count);

// Set a rate from the available rates - library handles decimation automatically
hydrasdr_set_samplerate(dev, rates[0]);  // Select from available rates
```

### Available Sample Rates (RFOne)

The library selects the **lowest hardware rate** by default (minimizes USB bandwidth):

| Effective Rate | HW Rate | Decimation |
|----------------|---------|------------|
| 10 MSPS | 10 MSPS | 1x |
| 5 MSPS | 5 MSPS | 1x |
| 2.5 MSPS | 2.5 MSPS | 1x |
| 1.25 MSPS | 2.5 MSPS | 2x |
| 625 kSPS | 2.5 MSPS | 4x |
| 312.5 kSPS | 2.5 MSPS | 8x |
| 156.25 kSPS | 2.5 MSPS | 16x |
| 78.125 kSPS | 2.5 MSPS | 32x |
| 39.0625 kSPS | 2.5 MSPS | 64x |

## Decimation Mode Selection (v1.1.0)

Two decimation strategies are available via `hydrasdr_set_decimation_mode()`:

| Mode | Strategy | Example (625 kSPS) | USB BW | Stages |
|------|----------|-------------------|--------|--------|
| **Low Bandwidth** (default) | Lowest HW rate | 2.5 MSPS / 4x | ~10 MB/s | 2 |
| **High Definition** | Highest HW rate | 10 MSPS / 16x | ~40 MB/s | 4 |

```c
// Query available sample rates and bandwidths first (device-specific)
uint32_t rate_count, bw_count;
hydrasdr_get_samplerates(dev, &rate_count, 0);
uint32_t *rates = malloc(rate_count * sizeof(uint32_t));
hydrasdr_get_samplerates(dev, rates, rate_count);

hydrasdr_get_bandwidths(dev, &bw_count, 0);
uint32_t *bandwidths = malloc(bw_count * sizeof(uint32_t));
hydrasdr_get_bandwidths(dev, bandwidths, bw_count);

// High Definition mode for better signal quality
hydrasdr_set_decimation_mode(dev, HYDRASDR_DEC_MODE_HIGH_DEFINITION);
hydrasdr_set_samplerate(dev, rates[i]);  // Select from available rates

// For maximum quality: combine with narrow RF bandwidth
hydrasdr_set_decimation_mode(dev, HYDRASDR_DEC_MODE_HIGH_DEFINITION);
hydrasdr_set_bandwidth(dev, bandwidths[0]);  // Select from available bandwidths
hydrasdr_set_samplerate(dev, rates[i]);  // Select from available rates
```

**Use cases**:
- **Low Bandwidth**: Battery-powered devices, USB 2.0 hubs, mobile applications
- **High Definition**: Desktop SDR, weak signal work, high dynamic range requirements

## Auto-Bandwidth Selection (v1.1.0)

The library automatically selects optimal RF bandwidth when `hydrasdr_set_samplerate()` is called:

| Scenario | Behavior |
|----------|----------|
| `hydrasdr_set_samplerate()` only | Auto-selects smallest BW >= hardware sample rate |
| `hydrasdr_set_bandwidth()` then `hydrasdr_set_samplerate()` | Uses manual BW (no auto) |

**Algorithm**: Finds the smallest available bandwidth that is >= **hardware** sample rate (not effective rate).

### Tuner Bandwidth Limitation

The tuner's IF filter (R820T/R828D) is only properly centered when the bandwidth matches the hardware sample rate. Setting a narrower bandwidth than the hardware rate causes the filter to be **off-center**, resulting in asymmetric frequency response.

| Mode | HW Rate | BW Setting | Filter Centering |
|------|---------|------------|------------------|
| Low Bandwidth | 5 MHz | 5 MHz | ✅ Centered |
| High Definition | 10 MHz (2x dec) | 10 MHz | ✅ Centered |
| High Definition | 10 MHz (2x dec) | 5.4 MHz | ⚠️ Off-center (usable) |

**Auto mode**: Selects BW matching hardware rate for optimal filter centering.

**Manual override**: Users can manually select a narrower bandwidth for better out-of-band rejection, accepting the off-center filter tradeoff. This is particularly useful with high decimation ratios:

| Effective Rate | HW Rate | Dec | Auto BW | Manual BW Option |
|----------------|---------|-----|---------|------------------|
| 312.5 kHz | 10 MHz | 32x | 10 MHz | 5.4 MHz (better rejection) |
| 625 kHz | 10 MHz | 16x | 10 MHz | 5.4 MHz (better rejection) |

**Tradeoff**: Narrower manual BW provides better analog pre-filtering at the cost of slightly off-center response. The DDC decimation filters handle the final bandwidth reduction digitally, so the off-center effect is often acceptable for narrowband applications.

```c
// Auto-bandwidth: library selects optimal BW
hydrasdr_set_samplerate(dev, 2500000);  // Auto-selects BW >= 2.5 MHz

// Manual bandwidth: user controls BW explicitly
hydrasdr_set_bandwidth(dev, 1750000);   // Set 1.75 MHz BW
hydrasdr_set_samplerate(dev, 2500000);  // Uses manual BW, no auto-selection
```

### Effective ADC Resolution Gain (v1.1.0)

Oversampling and decimation provide processing gain (Shannon/Nyquist theory):
- **Processing gain**: `SNR = 10 × log₁₀(N)` dB
- **Effective bits gained**: `ΔBits = 0.5 × log₂(N)`

| Decimation | Processing Gain | Bits Gained |
|------------|-----------------|-------------|
| 2x | 3.0 dB | +0.5 bits |
| 4x | 6.0 dB | +1.0 bit |
| 16x | 12.0 dB | +2.0 bits |
| 64x | 18.1 dB | +3.0 bits |

**Combined example** (625 kSPS with High Definition + narrow BW on RFOne):
- Base ADC: 12-bit (10.5 ENOB)
- 10 MSPS / 16x decimation: +12 dB (+2 bits)
- Narrow BW (~1.7 MHz) vs 10 MHz: ~7.7 dB (~1.3 bits)
- **Total**: ~20 dB improvement, 10.5 → **~13.8 ENOB** (equivalent to 18-bit ADC)

## Query Current Configuration (v1.1.0)

`hydrasdr_get_device_info()` can be called at any time, including during streaming, to query current configuration state:

```c
hydrasdr_device_info_t info;
hydrasdr_get_device_info(dev, &info);

// Current streaming configuration
printf("Effective rate: %u Hz\n", info.current_samplerate);
printf("Hardware rate:  %u Hz\n", info.current_hw_samplerate);
printf("Decimation:     %ux (%s mode)\n",
       info.current_decimation_factor,
       info.current_decimation_mode ? "High Definition" : "Low Bandwidth");
printf("Bandwidth:      %u Hz (%s)\n",
       info.current_bandwidth,
       info.bandwidth_auto_selected ? "auto" : "manual");
printf("Sample type:    %u\n", info.current_sample_type);
printf("Packing:        %s\n", info.current_packing ? "12-bit" : "16-bit");
```

### Current Configuration Fields

Fields ordered to match typical API call sequence: `decimation_mode` → `bandwidth` → `samplerate`

| Field | Description |
|-------|-------------|
| `current_decimation_mode` | 0=Low Bandwidth, 1=High Definition |
| `current_packing` | 0=16-bit, 1=12-bit packed |
| `bandwidth_auto_selected` | 1 if bandwidth was auto-selected, 0 if manual |
| `current_decimation_factor` | Decimation factor (1, 2, 4, 8, 16, 32, or 64) |
| `current_bandwidth` | Currently selected RF bandwidth in Hz |
| `current_samplerate` | Effective sample rate in Hz (after decimation) |
| `current_hw_samplerate` | Actual hardware/ADC sample rate in Hz |
| `current_sample_type` | Current sample type (enum hydrasdr_sample_type) |

## Thread Safety

- Device enumeration/opening: **NOT** thread-safe
- Device control (after open): **Thread-safe**
- Callbacks run in a dedicated thread
  - **Windows**: Elevated to `THREAD_PRIORITY_HIGHEST`
  - **Linux/macOS**: Normal priority (lock-free buffering handles timing jitter)

## Callback Timing (v1.1.0)

The SPSC queue provides headroom before data loss:

| Sample Rate | Buffer Interval | Queue Headroom (16 buffers) |
|-------------|-----------------|----------------------------|
| 10 MSPS | ~6.5 ms | **~105 ms** |
| 5 MSPS | ~13 ms | **~210 ms** |
| 2.5 MSPS | ~26 ms | **~420 ms** |

**Rule of thumb**:
- Occasional processing up to queue headroom time is safe
- For consistent processing, stay under the buffer interval
- Heavy DSP should be offloaded to another thread

Monitor streaming health:
```c
hydrasdr_streaming_stats_t stats;
hydrasdr_get_streaming_stats(dev, &stats);
printf("Buffers: received=%llu, processed=%llu, dropped=%llu\n",
       stats.buffers_received, stats.buffers_processed, stats.buffers_dropped);
```

## Building

See the parent directory README.md for complete build instructions.

### Quick Start (Linux/macOS)

```bash
mkdir build && cd build
cmake ..
make
```

### Quick Start (Windows with MSYS2/MinGW64)

```bash
mkdir build && cd build
cmake .. -G "Ninja"
ninja
```

## License

This library uses dual licensing:

- **MIT License**: Most files (see LICENSE.md for complete list)
- **BSD-3-Clause**: `hydrasdr.h` and `hydrasdr.c` (multi-author heritage)

Both licenses are permissive and compatible. See [LICENSE.md](LICENSE.md) for details.

## Links

- HydraSDR: https://www.hydrasdr.com
- Based on concepts from the HackRF project: https://greatscottgadgets.com/hackrf/