ka9q-python 3.7.0__tar.gz → 3.7.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/CHANGELOG.md +15 -0
- {ka9q_python-3.7.0/ka9q_python.egg-info → ka9q_python-3.7.1}/PKG-INFO +1 -1
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/ka9q/managed_stream.py +6 -1
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/ka9q/stream.py +18 -4
- {ka9q_python-3.7.0 → ka9q_python-3.7.1/ka9q_python.egg-info}/PKG-INFO +1 -1
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/pyproject.toml +1 -1
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/LICENSE +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/MANIFEST.in +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/README.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/RELEASE_NOTES_v3.5.0.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/API_REFERENCE.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/ARCHITECTURE.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/CHANGELOG.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/CROSS_PLATFORM_SUPPORT.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/DISTRIBUTION_RECOMMENDATION.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/GETTING_STARTED.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/INSTALLATION.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/MULTI_HOMED_QUICK_REF.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/NATIVE_DISCOVERY.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/PYPI_PUBLICATION_GUIDE.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/QUICK_REFERENCE.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/RTP_RECORDER_PASS_ALL_PACKETS.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/RTP_TIMING_IMPLEMENTATION.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/RTP_TIMING_SUPPORT.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/SECURITY.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/SSRC_COLLISION_PREVENTION.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/TESTING_GUIDE.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/TESTING_SUMMARY.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/TEST_RESULTS.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/WEB_UI_ENHANCEMENT_GUIDE.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/WEB_UI_ENHANCEMENT_IMPLEMENTED.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/WEB_UI_ESCAPE_SEQUENCE_FIX.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/WEB_UI_FUNCTIONALITY_REVIEW.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/WEB_UI_IMPLEMENTATION_STATUS.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/WEB_UI_INTERACTIVE_COMPLETE.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/development/CHANGES_SUMMARY.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/development/CHANNEL_CLEANUP_ADDITION.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/development/CHANNEL_CLEANUP_COMPLETE.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/development/CHANNEL_TUNING_DIAGNOSTICS.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/development/CODE_REVIEW_RECOMMENDATIONS.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/development/CODE_REVIEW_SUMMARY.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/development/COMMIT_SUMMARY.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/development/CRITICAL_FIXES_CHECKLIST.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/development/FINAL_SUMMARY.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/development/FIXES_SUMMARY.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/development/GIT_STATUS_SUMMARY.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/development/IMPLEMENTATION_COMPLETE.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/development/IMPLEMENTATION_STATUS.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/development/IMPLEMENTATION_SUMMARY.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/development/IMPLEMENTATION_SUMMARY_v2.2.0.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/development/IMPROVEMENTS_IMPLEMENTED.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/development/MULTI_HOMED_ACTION_PLAN.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/development/MULTI_HOMED_IMPLEMENTATION_COMPLETE.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/development/MULTI_HOMED_SUPPORT_REVIEW.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/development/PACKAGE_STATUS.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/development/PACKAGE_VERIFICATION.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/development/PERFORMANCE_FIXES_APPLIED.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/development/PERFORMANCE_REVIEW.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/development/PERFORMANCE_REVIEW_V2.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/development/PERFORMANCE_SUMMARY.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/development/QUICK_ACTION_ITEMS.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/development/QUICK_START_DIAGNOSIS.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/development/RELEASE_CHECKLIST_v3.0.0.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/development/SUMMARY.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/development/SUMMARY_WEB_UI_FIXES.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/development/TUNE_IMPLEMENTATION.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/development/WEBUI_SUMMARY.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/development/WEB_UI_ENHANCEMENTS_COMPLETE.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/features/CONTROL_COMPARISON.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/features/DESTINATION_AWARE_CHANNELS.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/features/NEW_FEATURES.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/features/RADIOD_FEATURES_SUMMARY.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/features/RTP_DESTINATION_FEATURE.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/releases/GITHUB_RELEASE_INSTRUCTIONS.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/releases/GITHUB_RELEASE_v2.2.0.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/releases/GITHUB_RELEASE_v2.4.0.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/releases/GITHUB_RELEASE_v2.5.0.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/releases/GITHUB_RELEASE_v3.0.0.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/releases/GITHUB_RELEASE_v3.1.0.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/releases/GITHUB_RELEASE_v3.2.0.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/releases/RELEASE_NOTES.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/releases/RELEASE_NOTES_v2.1.0.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/releases/RELEASE_NOTES_v2.2.0.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/releases/RELEASE_NOTES_v2.3.0.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/releases/RELEASE_NOTES_v2.4.0.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/releases/RTP_TIMING_RELEASE_NOTES.md +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/examples/advanced_features_demo.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/examples/channel_cleanup_example.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/examples/codar_oceanography.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/examples/diagnostics/diagnose_packets.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/examples/diagnostics/repro_utc_bug.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/examples/discover_example.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/examples/grape_integration_example.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/examples/hf_band_scanner.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/examples/rtp_recorder_example.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/examples/simple_am_radio.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/examples/stream_example.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/examples/superdarn_recorder.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/examples/test_channel_operations.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/examples/test_improvements.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/examples/test_timing_fields.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/examples/tune.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/examples/tune_example.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/ka9q/__init__.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/ka9q/addressing.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/ka9q/compat.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/ka9q/control.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/ka9q/discovery.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/ka9q/exceptions.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/ka9q/monitor.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/ka9q/pps_calibrator.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/ka9q/resequencer.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/ka9q/rtp_recorder.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/ka9q/stream_quality.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/ka9q/types.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/ka9q/utils.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/ka9q_python.egg-info/SOURCES.txt +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/ka9q_python.egg-info/dependency_links.txt +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/ka9q_python.egg-info/requires.txt +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/ka9q_python.egg-info/top_level.txt +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/ka9q_radio_compat +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/scripts/sync_types.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/setup.cfg +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/setup.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/tests/__init__.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/tests/conftest.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/tests/test_addressing.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/tests/test_channel_verification.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/tests/test_create_split_encoding.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/tests/test_decode_functions.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/tests/test_encode_functions.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/tests/test_encode_socket.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/tests/test_ensure_channel_encoding.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/tests/test_integration.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/tests/test_iq_20khz_f32.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/tests/test_listen_multicast.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/tests/test_managed_stream_recovery.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/tests/test_monitor.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/tests/test_multihomed.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/tests/test_native_discovery.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/tests/test_performance_fixes.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/tests/test_protocol_compat.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/tests/test_remove_channel.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/tests/test_rtp_recorder.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/tests/test_security_features.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/tests/test_ssrc_dest_unit.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/tests/test_ssrc_encoding_unit.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/tests/test_ssrc_radiod_host_unit.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/tests/test_ttl_warning.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/tests/test_tune.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/tests/test_tune_cli.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/tests/test_tune_debug.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/tests/test_tune_live.py +0 -0
- {ka9q_python-3.7.0 → ka9q_python-3.7.1}/tests/test_tune_method.py +0 -0
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [3.7.1] - 2026-04-12
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- **S16BE/S16LE audio parsing in `RadiodStream`**: `_parse_samples()` always decoded audio-mode RTP payloads as float32, regardless of the channel's actual encoding. When encoding was S16BE (used by FT4/FT8 channels at 12 kHz), a 240-byte payload containing 120 int16 samples was misinterpreted as 60 float32 values. The `PacketResequencer` then reported a 120-sample gap on every packet (~2500 gaps/minute), reducing stream completeness to ~37% and making the stream unusable for downstream consumers like `decode_ft8`. Now dispatches on `channel.encoding`: S16BE (`>i2`), S16LE (`<i2`), F32BE (`>f4`), and default F32LE (`np.float32`). All int16 formats are normalized to float32 (÷32768) in the callback.
|
|
8
|
+
- **`ManagedStream` now accepts `encoding` parameter**: Added `encoding: int = 0` to `__init__()`, passed through to both `ensure_channel()` call sites (initial provisioning and stream restoration). Without this, `ManagedStream` would re-provision a channel without encoding on restore, causing format mismatches. Clients using non-default encoding (S16BE, S16LE, F32BE) should pass `encoding=` to the constructor. This eliminates the need for hf-timestd's `RobustManagedStream` workaround.
|
|
9
|
+
|
|
10
|
+
### Client migration
|
|
11
|
+
|
|
12
|
+
- **Clients using `ManagedStream` with non-default encoding**: Pass `encoding=<int>` to the constructor. Example: `ManagedStream(control=ctl, frequency_hz=14.074e6, preset="usb", sample_rate=12000, encoding=2)` for S16BE.
|
|
13
|
+
- **Clients using bare `RadiodStream` with S16BE/S16LE**: No code change needed — samples are now correctly decoded to float32 in the callback. Note that if client code was compensating for the old bug (e.g., manually byte-swapping), that workaround should be removed.
|
|
14
|
+
- **hf-timestd**: Can replace `RobustManagedStream` (stream_recorder_v2.py lines 40-195) with `ka9q.ManagedStream(encoding=Encoding.F32)` and delete the wrapper class.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
3
18
|
## [3.7.0] - 2026-04-12
|
|
4
19
|
|
|
5
20
|
### Changed
|
|
@@ -123,6 +123,7 @@ class ManagedStream:
|
|
|
123
123
|
agc_enable: int = 0,
|
|
124
124
|
gain: float = 0.0,
|
|
125
125
|
destination: Optional[str] = None,
|
|
126
|
+
encoding: int = 0,
|
|
126
127
|
on_samples: Optional[SampleCallback] = None,
|
|
127
128
|
on_stream_dropped: Optional[StreamDroppedCallback] = None,
|
|
128
129
|
on_stream_restored: Optional[StreamRestoredCallback] = None,
|
|
@@ -135,7 +136,7 @@ class ManagedStream:
|
|
|
135
136
|
):
|
|
136
137
|
"""
|
|
137
138
|
Initialize ManagedStream.
|
|
138
|
-
|
|
139
|
+
|
|
139
140
|
Args:
|
|
140
141
|
control: RadiodControl instance for channel management
|
|
141
142
|
frequency_hz: Center frequency in Hz
|
|
@@ -144,6 +145,7 @@ class ManagedStream:
|
|
|
144
145
|
agc_enable: Enable AGC (0=off, 1=on)
|
|
145
146
|
gain: Manual gain in dB (when AGC off)
|
|
146
147
|
destination: RTP destination multicast address (optional)
|
|
148
|
+
encoding: Output encoding (0=none, 1=S16LE, 2=S16BE, 4=F32LE, etc.)
|
|
147
149
|
on_samples: Callback(samples, quality) for sample delivery
|
|
148
150
|
on_stream_dropped: Callback(reason) when stream drops
|
|
149
151
|
on_stream_restored: Callback(channel) when stream is restored
|
|
@@ -161,6 +163,7 @@ class ManagedStream:
|
|
|
161
163
|
self._agc_enable = agc_enable
|
|
162
164
|
self._gain = gain
|
|
163
165
|
self._destination = destination
|
|
166
|
+
self._encoding = encoding
|
|
164
167
|
|
|
165
168
|
# Callbacks
|
|
166
169
|
self._on_samples = on_samples
|
|
@@ -232,6 +235,7 @@ class ManagedStream:
|
|
|
232
235
|
agc_enable=self._agc_enable,
|
|
233
236
|
gain=self._gain,
|
|
234
237
|
destination=self._destination,
|
|
238
|
+
encoding=self._encoding,
|
|
235
239
|
)
|
|
236
240
|
|
|
237
241
|
# Start the underlying stream
|
|
@@ -414,6 +418,7 @@ class ManagedStream:
|
|
|
414
418
|
agc_enable=self._agc_enable,
|
|
415
419
|
gain=self._gain,
|
|
416
420
|
destination=self._destination,
|
|
421
|
+
encoding=self._encoding,
|
|
417
422
|
timeout=self._restore_interval_sec * 2, # Give it some time
|
|
418
423
|
)
|
|
419
424
|
|
|
@@ -350,7 +350,7 @@ class RadiodStream:
|
|
|
350
350
|
).isoformat()
|
|
351
351
|
|
|
352
352
|
def _parse_samples(self, payload: bytes) -> Optional[np.ndarray]:
|
|
353
|
-
"""Parse samples from RTP payload."""
|
|
353
|
+
"""Parse samples from RTP payload based on channel encoding."""
|
|
354
354
|
try:
|
|
355
355
|
if self._is_iq:
|
|
356
356
|
# IQ mode: float32 interleaved I/Q -> complex64
|
|
@@ -362,9 +362,23 @@ class RadiodStream:
|
|
|
362
362
|
samples = floats[0::2] + 1j * floats[1::2]
|
|
363
363
|
return samples.astype(np.complex64)
|
|
364
364
|
else:
|
|
365
|
-
# Audio mode:
|
|
366
|
-
|
|
367
|
-
|
|
365
|
+
# Audio mode: parse according to encoding
|
|
366
|
+
enc = getattr(self.channel, 'encoding', 0)
|
|
367
|
+
if enc == 2:
|
|
368
|
+
# S16BE: 16-bit big-endian signed integers -> float32
|
|
369
|
+
int16_samples = np.frombuffer(payload, dtype='>i2')
|
|
370
|
+
return (int16_samples / 32768.0).astype(np.float32)
|
|
371
|
+
elif enc == 1:
|
|
372
|
+
# S16LE: 16-bit little-endian signed integers -> float32
|
|
373
|
+
int16_samples = np.frombuffer(payload, dtype='<i2')
|
|
374
|
+
return (int16_samples / 32768.0).astype(np.float32)
|
|
375
|
+
else:
|
|
376
|
+
# F32LE (4), F32BE (8), or default: float32
|
|
377
|
+
if enc == 8:
|
|
378
|
+
return np.frombuffer(payload, dtype='>f4').astype(np.float32)
|
|
379
|
+
else:
|
|
380
|
+
return np.frombuffer(payload, dtype=np.float32)
|
|
381
|
+
|
|
368
382
|
except Exception as e:
|
|
369
383
|
logger.error(f"Failed to parse payload: {e}")
|
|
370
384
|
return None
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ka9q_python-3.7.0 → ka9q_python-3.7.1}/docs/development/MULTI_HOMED_IMPLEMENTATION_COMPLETE.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|