Лабораторная 9.4 — Чтение WAV IQ и офлайн-анализ¶
Цель¶
Научиться читать WAV IQ запись через manifest, восстанавливать комплексные отсчёты, строить FFT и получать воспроизводимые метрики для реальных захватов.
Что выполняется¶
В работе студент:
- берёт manifest с checksum и локальным path hint;
- читает двухканальный
WAV IQфайл; - интерпретирует каналы как
I/Q; - считает spectrum, peak, SNR, DC offset и clipping fraction;
- сохраняет графики и metrics JSON.
Подробная техническая часть¶
Зачем это нужно¶
Большинство «реальных» SDR-данных, которые вам встретятся это не красивые файлы .ci16 из курса, а WAV-записи из SDR-приложений: HDSDR, SDR#, GQRX и т. п. пишут IQ как стереофайл, где левый канал это I, а правый это Q. Прежде чем что-либо анализировать, нужно убедиться, что вы верно прочитали такой файл: не перепутан порядок каналов, верна разрядность, известны частота дискретизации и центральная частота. Ошибка на этом шаге (перепутанные I и Q зеркально отражают спектр) незаметна на графиках и молча портит всё дальнейшее. Поэтому чтение идёт через манифест, а не через догадки по имени файла, а результат это метрики, которые можно воспроизвести.
Исполняемые файлы¶
| Среда | Файл | Результат |
|---|---|---|
| Python | blocks/block_09_recording_and_analysis_tools/python/lab_9_4_read_wav_iq_and_analyze.py |
график спектра, превью во времени, JSON с метриками |
| YAML / JSON | манифест набора данных | подсказка пути к файлу, частота дискретизации, центральная частота, ожидаемое смещение сигнала |
Запуск из корня репозитория:
python blocks/block_09_recording_and_analysis_tools/python/lab_9_4_read_wav_iq_and_analyze.py \
--manifest datasets/lab1_0_rtl_sdr_observation/manifest_narrowband_220860000.yaml
Для записи в FM-диапазоне:
python blocks/block_09_recording_and_analysis_tools/python/lab_9_4_read_wav_iq_and_analyze.py \
--manifest datasets/lab1_0_rtl_sdr_observation/manifest_fm_103119454.yaml
Сгенерированные артефакты:
docs/assets/lab94_<dataset_id>_spectrum.png
docs/assets/lab94_<dataset_id>_time_preview.png
docs/assets/<dataset_id>_metrics.json
Цепочка обработки¶
flowchart LR
MANIFEST[Манифест набора данных] --> RESOLVE[Определение локального пути к WAV IQ]
RESOLVE --> READ[Чтение стерео WAV IQ]
READ --> MAP[Каналы левый/правый в комплексные I/Q]
MAP --> FFT[Анализ FFT]
MAP --> QC[Проверки DC/ограничения]
FFT --> METRICS[Пик, SNR, частотная ошибка]
QC --> METRICS
METRICS --> REPORT[Графики + JSON с метриками]
Поддерживаемые допущения о WAV IQ¶
- стерео WAV-контейнер;
- канал 1 =
I, канал 2 =Qпо умолчанию; - данные PCM в формате little-endian;
- целочисленный PCM
8-bit,16-bitили32-bit; sample_rate_hzиcenter_frequency_hzберутся из манифеста.
Если запись использует другой порядок каналов, задайте в манифесте i_first: false.
Метрики¶
| Метрика | Смысл |
|---|---|
sample_count_read |
число комплексных отсчётов, восстановленных из WAV-файла |
measured_peak_hz |
сильнейший пик FFT относительно основной полосы |
frequency_error_hz |
измеренный пик минус ожидаемое смещение |
snr_db |
уровень пика минус оценка медианного уровня шума |
dc_offset_magnitude |
модуль среднего комплексного отсчёта |
clipping_fraction |
доля отсчётов, близких к полной шкале |
quality_pass |
быстрая проверка «прошёл/не прошёл» по необязательным порогам из манифеста |
Переход к реальным захватам¶
Предполагаемый путь:
приватный WAV IQ + manifest.yaml -> читатель -> FFT + QC -> графики + метрики -> отчёт
Так исходный файл остаётся вне Git, а анализ при этом воспроизводим.
В репозитории лежат две демонстрационные записи RTL-SDR (по ~50 МБ, хранятся через Git LFS в datasets/lab1_0_rtl_sdr_observation/raw/, контрольные суммы в манифестах), поэтому команды выше воспроизводятся «из коробки». Для собственных больших записей используйте тот же манифест, но держите файл вне Git.
Чего ожидать¶
Для узкополосной записи на 220,86 МГц (реальный захват RTL-SDR, а не синтетика) запуск печатает:
Samples read: 12741632
Sample rate: 2400000 Hz
Center frequency: 220860000 Hz
Expected offset: 0.000 Hz
Measured peak: 0.000 Hz
Frequency error: 0.000 Hz
SNR estimate: 39.58 dB
DC offset magnitude: 0.004375
Clipping fraction: 0.000000e+00
Quality pass: True
Как читать:
- 12 741 632 отсчёта при 2,4 МС/с это примерно 5,3 с записи.
- Пик ровно на 0 Гц и «SNR 39,6 дБ». Манифест ожидает сигнал в центре полосы (
expected_signal_offset_hz: 0). По одному спектру нельзя отличить настоящую узкополосную несущую от собственного DC-пика приёмника (см. Лабораторную 6.5); честный приём это повторить запись со смещённой центральной частотой: сигнал сместится, артефакт DC останется на нуле. И помните, чтоsnr_dbздесь это пик над медианной шумовой полкой, а не качество канала связи. - DC 0,0044 и ноль ограничений: запись не перегружена; по этим двум числам её можно считать пригодной для дальнейшего анализа.
Чек-лист отчёта (расширенный)¶
- Приложены путь к манифесту и SHA256.
- Указаны частота дискретизации и центральная частота.
- Подтверждены число каналов WAV и разрядность отсчёта.
- Приложен график спектра.
- Приложено превью во временной области.
- Указаны частота пика, SNR, смещение DC и доля ограничения.
- Указано, где хранится исходный файл и почему его нет в Git.
Шаблон инженерного вывода¶
Запись WAV IQ ____ содержит ____ комплексных отсчётов при ____ МС/с.
Измеренный пик находится на ____ кГц относительно основной полосы, оценка SNR ____ дБ,
модуль смещения DC ____, доля ограничения ____.
Файл пригоден / не пригоден для дальнейшего воспроизведения или демодуляции, потому что ______.