Skip to content

Fix stdout binary mode reset on Windows before streaming starts - #108

Open
droggen wants to merge 1 commit into
rxseger:masterfrom
droggen:fix-windows-stdout-binary-mode
Open

Fix stdout binary mode reset on Windows before streaming starts#108
droggen wants to merge 1 commit into
rxseger:masterfrom
droggen:fix-windows-stdout-binary-mode

Conversation

@droggen

@droggen droggen commented Jul 18, 2026

Copy link
Copy Markdown

Running rx_fm piped to sox or ffplay on Windows 11 leads to broken audio: crackling, no sound coming out. The issue is a text/binary mode problem in piping the output of rx_fm, where Windows resets the binary/text mode rather than preserving it.

On Windows, suppress_stdout_stop() calls dup2() to restore the original stdout file descriptor after device enumeration/setup logging is redirected away. Windows' dup2() resets the destination descriptor to text mode as part of this restore, silently undoing the earlier _setmode(..., _O_BINARY) call made when output.file was set to stdout in main().

This caused every 0x0A byte in the raw audio/IQ sample stream written to stdout to be corrupted by CRLF translation when rx_fm/ rx_sdr output was piped to another process (e.g. sox, ffplay, direwolf) on Windows. Writing directly to a file was unaffected, since that code path does not go through suppress_stdout_stop().

Fix: re-apply _setmode(..., _O_BINARY) immediately after suppress_stdout_stop() in dongle_thread_fn, the last place stdout's mode is touched before the write loop begins.

Verified by measuring 0x0D 0x0A byte-pair density in captured pipe output: ~0.7-1.3% before the fix vs ~0.002-0.005% baseline for clean random PCM data; ~0.004% after the fix, matching baseline.

Running rx_fm piped to sox or ffplay on Windows 11 leads to broken
audio: crackling, no sound coming out. The issue is a text/binary
mode problem in piping the output of rx_fm, where Windows resets
the binary/text mode rather than preserving it.

On Windows, suppress_stdout_stop() calls dup2() to restore the
original stdout file descriptor after device enumeration/setup
logging is redirected away. Windows' dup2() resets the destination
descriptor to text mode as part of this restore, silently undoing
the earlier _setmode(..., _O_BINARY) call made when output.file was
set to stdout in main().

This caused every 0x0A byte in the raw audio/IQ sample stream
written to stdout to be corrupted by CRLF translation when rx_fm/
rx_sdr output was piped to another process (e.g. sox, ffplay,
direwolf) on Windows. Writing directly to a file was unaffected,
since that code path does not go through suppress_stdout_stop().

Fix: re-apply _setmode(..., _O_BINARY) immediately after
suppress_stdout_stop() in dongle_thread_fn, the last place stdout's
mode is touched before the write loop begins.

Verified by measuring 0x0D 0x0A byte-pair density in captured pipe
output: ~0.7-1.3% before the fix vs ~0.002-0.005% baseline for clean
random PCM data; ~0.004% after the fix, matching baseline.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant