FreeDATA/freedata_server
Steve Pinkham f522b46fa8 fix(audio): re-block captured RX audio into whole DSP blocks
With blocksize=0 PortAudio picks the capture block size per device. On
the devices measured for the previous commit it happened to deliver
multiple-of-6 block sizes, but other hardware returns 512/1024-class
blocks. codec2's resample48_to_8 asserts len(input) % 6 == 0
(FDMDV_OS_48), so on such a device every captured block raised
AssertionError, the DSP chain never ran, and RX was completely deaf.

The fix decouples the capture block size from the DSP block size
instead of pinning the stream back to blocksize=4800, which is the
configuration that negotiates a two-period ring on snd-aloop and drops
audio continuously (the deaf-on-loopback case the previous commit
fixed). Captured audio is appended to a carry buffer and the DSP chain
runs once per whole RX_DSP_BLOCK_48K (4800 samples, 100 ms) available;
the remainder carries into the next captured block, so the sample
stream handed to the resampler stays gapless (its filter memory spans
blocks) and always has a valid length, whatever the device delivers.

Running the DSP only on whole 4800-sample blocks also fixes three
silent degradations that short blocks caused:

- calculate_fft pads its input to 800 samples at 8 kHz, so short
  blocks fed the waterfall, channel-busy detection and audio_dbfs
  mostly zeros
- enqueue_streaming_audio_chunks zero-pads every block up to 2400
  samples and emits one chunk per block regardless of size, so short
  blocks streamed mostly silence and flooded the RX audio queue
- normalize_audio (rx_auto_audio_level, on by default) normalizes per
  block, so shorter blocks made the auto level faster and jumpier

Tests: the old test captured 4800-frame blocks, a multiple of 6, which
is exactly why this was never caught. The capture size is now 512 and
TestRxAudioReblocking covers odd sizes never reaching the resampler,
exact block accounting including the carried remainder, sample-stream
preservation (nothing dropped, duplicated or reordered), and every
re-blocked block being accepted end to end by the real codec2
resampler. Against the pre-fix code 5 of the 6 tests fail; with the
fix all pass.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 21:34:19 -04:00
..
api fix: send_arq_raw referenced a command class that doesn't exist 2026-07-12 12:38:16 -04:00
lib/codec2 support for M1+ chips 2026-01-09 08:42:12 +01:00
norm Fixed other module's paths 2026-01-10 20:27:19 +01:00
.gitignore another folder renaming 2024-04-18 11:04:25 +02:00
__init__.py another folder renaming 2024-04-18 11:04:25 +02:00
adif_udp_logger.py Increased max line length to 120, reformatted everything 2026-01-10 19:11:26 +01:00
api_validations.py Run `ruff format` 2025-11-13 15:53:43 +01:00
arq_data_type_handler.py Increased max line length to 120, reformatted everything 2026-01-10 19:11:26 +01:00
arq_session.py Increased max line length to 120, reformatted everything 2026-01-10 19:11:26 +01:00
arq_session_irs.py fix: emit arq-session-finished on IRS success again (lost April 2024) 2026-07-22 18:30:05 -04:00
arq_session_iss.py Increased max line length to 120, reformatted everything 2026-01-10 19:11:26 +01:00
audio.py Increased max line length to 120, reformatted everything 2026-01-10 19:11:26 +01:00
audio_buffer.py Executed `ruff format --preview`, small update to CONTRIBUTING.md 2025-11-13 23:48:17 +01:00
b64.py Increased max line length to 120, reformatted everything 2026-01-10 19:11:26 +01:00
codec2.py Increased max line length to 120, reformatted everything 2026-01-10 19:11:26 +01:00
codec2_filter_coeff.py Run `ruff format` 2025-11-13 15:53:43 +01:00
command.py Removed unused imports 2025-11-13 20:12:55 +01:00
command_arq_raw.py Removed unused imports 2025-11-13 20:12:55 +01:00
command_beacon.py Switched from editing `sys.path` to proper PEP8 imports 2025-11-13 19:49:38 +01:00
command_cq.py Removed unused imports 2025-11-13 20:12:55 +01:00
command_fec.py Increased max line length to 120, reformatted everything 2026-01-10 19:11:26 +01:00
command_message_send.py Increased max line length to 120, reformatted everything 2026-01-10 19:11:26 +01:00
command_norm.py Fixed other module's paths 2026-01-10 20:27:19 +01:00
command_p2p_connection.py Removed unused imports 2025-11-13 20:12:55 +01:00
command_ping.py Switched from editing `sys.path` to proper PEP8 imports 2025-11-13 19:49:38 +01:00
command_qrv.py Switched from editing `sys.path` to proper PEP8 imports 2025-11-13 19:49:38 +01:00
command_test.py Removed unused imports 2025-11-13 20:12:55 +01:00
command_transmit_sine.py Switched from editing `sys.path` to proper PEP8 imports 2025-11-13 19:49:38 +01:00
config.ini.example make norm a setting - trying to merge this PR soon 2026-01-08 16:48:25 +01:00
config.py Increased max line length to 120, reformatted everything 2026-01-10 19:11:26 +01:00
constants.py Increased max line length to 120, reformatted everything 2026-01-10 19:11:26 +01:00
context.py Merge branch 'develop' into ls-audio 2026-01-08 17:27:47 +01:00
cw.py Run `ruff format` 2025-11-13 15:53:43 +01:00
data_frame_factory.py Fixed other module's paths 2026-01-10 20:27:19 +01:00
demodulator.py Increased max line length to 120, reformatted everything 2026-01-10 19:11:26 +01:00
event_manager.py Executed `ruff format --preview`, small update to CONTRIBUTING.md 2025-11-13 23:48:17 +01:00
exceptions.py Run `ruff format` 2025-11-13 15:53:43 +01:00
explorer.py Increased max line length to 120, reformatted everything 2026-01-10 19:11:26 +01:00
flrig.py Removed redefined set_tuner() flrig's function (ruff F811) 2025-11-13 23:43:04 +01:00
frame_dispatcher.py Fixed ruff F811 and F401 2026-01-10 19:11:47 +01:00
frame_handler.py Increased max line length to 120, reformatted everything 2026-01-10 19:11:26 +01:00
frame_handler_arq_session.py Increased max line length to 120, reformatted everything 2026-01-10 19:11:26 +01:00
frame_handler_beacon.py Removed unused imports 2025-11-13 20:12:55 +01:00
frame_handler_cq.py Removed unused imports 2025-11-13 20:12:55 +01:00
frame_handler_norm.py Fixed ruff F811 and F401 2026-01-10 19:11:47 +01:00
frame_handler_p2p_connection.py Removed unused imports 2025-11-13 20:12:55 +01:00
frame_handler_ping.py Increased max line length to 120, reformatted everything 2026-01-10 19:11:26 +01:00
helpers.py Increased max line length to 120, reformatted everything 2026-01-10 19:11:26 +01:00
list_ports_winreg.py Run `ruff format` 2025-11-13 15:53:43 +01:00
log_handler.py Run `ruff format` 2025-11-13 15:53:43 +01:00
maidenhead.py Fixed ruff F841 2026-01-10 19:11:47 +01:00
message_p2p.py Increased max line length to 120, reformatted everything 2026-01-10 19:11:26 +01:00
message_system_db_attachments.py Increased max line length to 120, reformatted everything 2026-01-10 19:11:26 +01:00
message_system_db_beacon.py Increased max line length to 120, reformatted everything 2026-01-10 19:11:26 +01:00
message_system_db_broadcasts.py linting 2026-07-23 08:59:21 +02:00
message_system_db_manager.py Increased max line length to 120, reformatted everything 2026-01-10 19:11:26 +01:00
message_system_db_messages.py Increased max line length to 120, reformatted everything 2026-01-10 19:11:26 +01:00
message_system_db_model.py Fixed ruff E7 2026-01-10 19:11:47 +01:00
message_system_db_station.py Increased max line length to 120, reformatted everything 2026-01-10 19:11:26 +01:00
modem.py fix(audio): re-block captured RX audio into whole DSP blocks 2026-07-24 21:34:19 -04:00
modem_frametypes.py Increased max line length to 120, reformatted everything 2026-01-10 19:11:26 +01:00
modulator.py Removed unused imports 2025-11-13 20:12:55 +01:00
p2p_connection.py Increased max line length to 120, reformatted everything 2026-01-10 19:11:26 +01:00
radio_manager.py Increased max line length to 120, reformatted everything 2026-01-10 19:11:26 +01:00
rigctld.py Increased max line length to 120, reformatted everything 2026-01-10 19:11:26 +01:00
rigdummy.py Run `ruff format` 2025-11-13 15:53:43 +01:00
schedule_manager.py Fixed ruff F811 and F401 2026-01-10 19:11:47 +01:00
serial_ports.py Switched from editing `sys.path` to proper PEP8 imports 2025-11-13 19:49:38 +01:00
serial_ptt.py Run `ruff format` 2025-11-13 15:53:43 +01:00
server.py Fix a logger error message on win everytime an api call is mode 2026-02-10 20:39:35 -05:00
service_manager.py Increased max line length to 120, reformatted everything 2026-01-10 19:11:26 +01:00
socket_interface.py Increased max line length to 120, reformatted everything 2026-01-10 19:11:26 +01:00
socket_interface_commands.py Substituted unused variables with wildcard (ruff F841) 2025-11-13 23:31:09 +01:00
socket_interface_data.py Run `ruff format` 2025-11-13 15:53:43 +01:00
state_manager.py Increased max line length to 120, reformatted everything 2026-01-10 19:11:26 +01:00
stats.py Substituted unused variables with wildcard (ruff F841) 2025-11-13 23:31:09 +01:00
wavelog_api_logger.py Increased max line length to 120, reformatted everything 2026-01-10 19:11:26 +01:00
websocket_manager.py Fixed ruff F811 and F401 2026-01-10 19:11:47 +01:00