Commit Graph

58 Commits

Author SHA1 Message Date
Alex P a6cbf20f66 Fix audio capture to force Opus-compatible sample rates
ALSA now forces the configured sample rate (default 48kHz) instead of
auto-detecting the source rate. This prevents Opus encoder initialization
failures when HDMI sources output 44.1kHz audio, which Opus doesn't support.

Changes:
- Use snd_pcm_hw_params_set_rate() to force exact rate (48kHz by default)
- ALSA performs software resampling if hardware rate differs
- Update valid rates to Opus-compatible only (8k, 12k, 16k, 24k, 48k)
- Remove auto-adaptation logic that caused Opus failures with 44.1kHz

This ensures audio capture works reliably with any HDMI source rate.
2025-11-21 00:02:29 +02:00
Alex P 41604626cf Remove inaccurate and redundant comments
Fix comment inaccuracies:
- NEON: Change from "required" to "optimizations" (scalar fallback exists)
- capture_channels: Remove "always stereo" claim (configurable via API)

Remove redundant comments that duplicate code:
- "Apply boolean flags directly" (line duplicates what code does)
- Mutex comments in setAudioTrack (visible from code structure)

Also remove accidentally committed review artifacts (PR_REVIEW.md, jetkvm_default_edid.bin).
2025-11-19 17:19:46 +02:00
Alex P 3897a61729 Fix critical comment inaccuracies in audio code
- Fix validateAndApply comment to clarify it returns values, doesn't apply them
- Correct capture_channels comment about hardware capabilities
- Fix opus_packet_loss_perc default value from 0 to 20 (matches backend default)
- Fix handle_alsa_error return value documentation (return 0 also unlocks mutex)
2025-11-19 17:19:46 +02:00
Alex P 1d570a8cbf Fix critical audio race conditions and improve reliability
- Replace volatile with C11 atomics for proper ARM memory barriers
- Fix race condition in audio source swapping (swap to nil before cleanup)
- Prevent double-close of ALSA handles via atomic ownership claim
- Add exponential backoff with 10-retry circuit breaker to prevent infinite loops
- Improve error propagation to report dual failures
- Add defensive null checks for concurrent access safety
- Simplify UI error handling with helper functions
- Fix TypeScript compilation error in packet loss dropdown
2025-11-19 17:19:46 +02:00
Alex P ee23e3bf22 Refactor audio subsystem for improved maintainability
Changes:
- Consolidate duplicate stop logic into helper functions
- Fix RPC getAudioConfig to return actual runtime values instead of
  inconsistent defaults (bitrate was returning 128 vs actual 192)
- Improve setAudioTrack mutex handling to eliminate nested locking
- Simplify ALSA error retry logic by reorganizing conditional branches
- Split CGO Connect() into separate input/output methods for clarity
- Use map lookup for sample rate validation instead of long if-chain
- Add inline comments documenting validation steps

All changes preserve existing functionality while reducing code
duplication and improving readability. Tested with both HDMI and
USB audio sources.
2025-11-19 13:42:51 +02:00
Alex P c88b98c1f0 Fix critical audio race conditions and align configuration defaults
Critical Fixes:
- Fix race condition in handleInputTrackForSession by reloading source inside mutex
- Fix ALSA handle cleanup atomicity (nullify before close to prevent use-after-free)
- Bounds check for opus buffer already present (verified)

Configuration Alignment:
- Align audio bitrate default to 192 kbps across all layers (C, Go defaults, config)
- Align audio complexity default to 8 across all layers
- Align DTX default to enabled (true/1) across all layers for bandwidth efficiency

Documentation Improvements:
- Update C header comment to reflect accurate 192 kbps default
- Clarify NEON requirement (not just "always available")
- Fix ALSA device mapping comments to reflect environment variable usage
- Document fallback behavior in playback init

Code Quality:
- Add validation logging for out-of-range audio configuration values
- Improve error visibility for configuration issues

All changes thoroughly analyzed before implementation.
2025-11-18 16:37:44 +02:00
Alex P da4c6c70d2 Use efficient uint8_t for recovery attempt counters
Change recovery_attempts from int to uint8_t for better efficiency:
- Reduces memory footprint (1 byte vs 4 bytes)
- Better cache utilization on ARM
- Matches max_attempts type (uint8_t)
- Values never exceed 3, fits perfectly in uint8_t range

Updated function signature and all call sites for consistency.
2025-11-18 15:32:55 +02:00
Alex P befdfc7ce6 Fix type mismatch in ALSA error handler
Change recovery_attempts from uint8_t to int to match
handle_alsa_error signature and eliminate compiler warnings.
2025-11-18 14:38:12 +02:00
Alex P 0e299aac38 Deduplicate ALSA error handling and cleanup code
Extract shared error recovery logic:
- Create handle_alsa_error() for EPIPE, EAGAIN, ESTRPIPE, EIO errors
- Consolidates ~180 lines of duplicate error handling code
- Used by both capture and playback paths

Extract shared close logic:
- Create close_audio_stream() for safe shutdown sequence
- Handles CAS synchronization, delay, mutex protection
- Used by both jetkvm_audio_capture_close and jetkvm_audio_playback_close

Remove all TRACE_LOG dead code:
- TRACE_LOG was compiled to ((void)0) with zero runtime value
- Eliminates ~30 statements cluttering the codebase

Result: 87 lines removed (9% reduction), improved maintainability
2025-11-18 14:34:21 +02:00
Alex P 0022599b03 Fix audio channel separation and improve quality defaults
- Separate capture_channels (stereo HDMI) from playback_channels (mono mic)
  to prevent initialization conflicts that were breaking stereo output
- Optimize defaults for LAN use: 192kbps bitrate, complexity 8, 0% packet
  loss compensation, DTX disabled (eliminates static and improves clarity)
- Add comprehensive race condition protection in C audio layer with handle
  validity checks and mutex-protected cleanup operations
- Enable USB audio volume control and configure microphone as mono
- Add centralized AUDIO_DEFAULTS constant in UI with localized labels
- Add missing time import to fix compilation

This resolves audio quality issues and crash scenarios when switching
between HDMI and USB audio sources.
2025-11-18 13:38:06 +02:00
Alex P cd2d4d752c Remove additional redundant comments 2025-11-18 02:01:12 +02:00
Alex P a6b7ac50ef Eliminate hang completely by making ALSA interruption immediate
Problem:
Previous fix reduced but didn't eliminate the hang when switching audio
sources. The C layer was still blocking on snd_pcm_readi()/snd_pcm_writei()
while holding the mutex, preventing cleanup from proceeding.

Solution:
Call snd_pcm_drop() BEFORE acquiring the mutex in close functions. This
immediately interrupts any blocking ALSA read/write operations, causing them
to return with -EBADFD or -ESTRPIPE. The sequence is now:

1. Set stop_requested flag
2. Call snd_pcm_drop() to interrupt blocking I/O (no mutex needed - thread-safe)
3. Acquire mutex for cleanup
4. Close handles and free resources
5. Release mutex

This makes audio source switching instantaneous with zero hang.

Changes:
- jetkvm_audio_capture_close(): Drop PCM before mutex
- jetkvm_audio_playback_close(): Drop PCM before mutex

Tested: USB↔HDMI switching now happens instantly with no delay.
2025-11-18 01:46:29 +02:00
Alex P d7dc8c2075 Update audio.c header comment to reflect variable sample rate 2025-11-18 00:54:04 +02:00
Alex P 2b276e1ba5 Remove unused update_opus_encoder_params function 2025-11-18 00:53:15 +02:00
Alex P 94cab8b2ac Fix: prevent race condition crash in audio playback using pthread mutexes
Root cause: ALSA assertion failure `snd_pcm_writei: Assertion 'pcm' failed`
when pcm_playback_handle became NULL during concurrent write operations.

The crash occurred because:
1. Thread A checks pcm_playback_handle != NULL (passes)
2. Thread B calls jetkvm_audio_playback_close(), sets handle = NULL
3. Thread A calls snd_pcm_writei(NULL, ...) → SIGABRT

Solution: Added pthread mutexes to protect concurrent access:
- playback_mutex protects pcm_playback_handle in decode_write and close
- capture_mutex protects pcm_capture_handle in read_encode and close

All critical sections now acquire mutex before accessing ALSA handles,
preventing the NULL pointer from being passed to ALSA functions.
2025-11-18 00:53:15 +02:00
Alex P 236291a454 Fix: eliminate audio warping by auto-adapting to actual device sample rate
Root cause: ALSA was silently using a different sample rate than configured,
causing severe pitch/speed distortion (the "cassette player" warping effect).

The bug occurred when:
- User configured 48 kHz in UI
- HDMI source output 44.1 kHz audio
- set_rate() failed, set_rate_near() chose 44.1 kHz
- Code never checked what rate was actually set
- Opus encoder created for 48 kHz but received 44.1 kHz audio
- Result: ~9% pitch shift and timing mismatch

Fix:
- Always use set_rate_near() and check the actual rate returned
- Pass detected rate and frame size to Opus encoder/decoder creation
- Avoid modifying global state to prevent capture/playback interference
- Recalculate frame_size for 20ms at the actual rate
- Verify rate after hw_params application
- Add detailed logging for rate adaptation

This ensures Opus encoder/decoder use the correct rate matching the hardware,
regardless of what the HDMI source outputs.
2025-11-18 00:53:15 +02:00
Alex P 11dadebb93 Fix: improve EDID compatibility and add audio configuration options
- Update default EDID with registered manufacturer ID (Dell) and proper 24-inch display dimensions (52x32cm) for better macOS/OS compatibility
- Add configurable sample rate (32/44.1/48/96 kHz) to support different HDMI audio sources
- Add packet loss compensation percentage control for FEC overhead tuning
- Fix config migration to ensure new audio parameters get defaults for existing configs
- Update all language translations for new audio settings
2025-11-18 00:53:15 +02:00
Alex P 922a7158e7 Add runtime configurable audio parameters with UI controls
- Add config fields for bitrate, complexity, DTX, FEC, buffer periods
- Add RPC methods for get/set audio config and restart
- Add UI settings page with controls for all audio parameters
- Add Apply Settings button to restart audio with new config
- Add config migration for backwards compatibility
- Add translations for all 9 languages
- Clean up redundant comments and optimize log levels
2025-11-17 21:51:08 +02:00
Alex P e79c6f730e Add audio output source switching and improve shutdown handling
- Add HDMI/USB audio source selection in settings UI
- Add stop flags for graceful audio shutdown
- Use immediate PCM drop instead of drain for faster switching
- Add HDMI connection refresh RPC method
- Add GetDefaultEDID helper method
2025-11-17 20:45:34 +02:00
Alex P 17f52414ac Fix: increase ALSA buffer size to reduce audio crackling
Increase buffer from 80ms (4 periods) to 240ms (12 periods) for
better jitter tolerance on USB gadget audio capture.
2025-11-17 13:50:21 +02:00
Alex P 8caa5fc188 refactor: Remove subprocess audio infrastructure, use CGO-only
Remove all subprocess-based audio code to simplify the audio system and
reduce complexity. Audio now uses CGO in-process mode exclusively.

Changes:
- Remove subprocess mode: Deleted Supervisor, IPCSource, embed.go
- Remove audio mode selection from UI (Settings → Audio)
- Remove audio mode from backend config (AudioMode field)
- Remove JSON-RPC handlers: getAudioMode/setAudioMode
- Remove Makefile targets: build_audio_output/input/binaries
- Remove standalone C binaries: jetkvm_audio_{input,output}.c
- Remove IPC protocol implementation: ipc_protocol.{c,h}
- Remove unused IPC functions from audio_common.{c,h}
- Simplify audio.go: startAudio() instead of startAudioSubprocesses()
- Update all function calls and comments to remove subprocess references
- Add constants to cgo_source.go (ipcMaxFrameSize, ipcMsgTypeOpus)
- Keep update_opus_encoder_params() for potential future runtime config

Benefits:
- Simpler codebase: -1,734 lines of code
- Better performance: No IPC overhead on embedded hardware
- Easier maintenance: Single audio implementation
- Smaller binary: No embedded audio subprocess binaries

The audio system now works exclusively via CGO direct C function calls,
with ALSA device selection (HDMI vs USB) still configurable via settings.
2025-10-07 13:34:03 +03:00
Alex P 6728c492a1 feat: Optimize audio quality and default to USB audio
Audio quality improvements:
- Enable constrained VBR to prevent bitrate starvation at low volumes
- Increase Opus complexity from 2 to 5 for better quality
- Enable DTX for bandwidth optimization
- Enable FEC (Forward Error Correction)
- Add DTX and FEC signaling in SDP (usedtx=1;useinbandfec=1)

Default configuration changes:
- Change default audio output source from HDMI to USB
- Enable USB Audio device by default
- USB audio works on current stable image (HDMI requires newer device tree)

These changes fix crackling issues at low volumes and provide better
overall audio quality for both USB and HDMI audio paths.
2025-10-07 01:38:42 +03:00
Alex P 3b609d2b67 refactor: Simplify audio implementation
Remove dynamic gain code and rely on Opus encoder quality improvements:
- Increase Opus complexity from 2 to 5 for better quality
- Change bandwidth from FULLBAND (20kHz) to SUPERWIDEBAND (16kHz) for better quality at 128kbps
- Disable FEC to allocate all bits to audio quality
- Increase ALSA buffer from 40ms to 80ms for stability

The dynamic gain code was adding complexity without solving the underlying
issue: TC358743 HDMI chip captures digital audio at whatever volume the
source outputs. Users should adjust volume at the source or in their browser.
2025-10-07 00:25:45 +03:00
Alex P 639eecbb93 fix: Add noise gate to prevent amplifying silence artifacts
Add noise gate threshold at peak > 256 (-42dB) to prevent dynamic gain
from amplifying quantization noise and hardware noise floor. This fixes
crackling, buzzing, and static-like noise when HDMI audio is at very
low volume or during silence.

Without the gate, signals below -42dB (peak < 256) would get 8x gain
applied, amplifying noise floor to audible levels. Now these signals
pass through unmodified, eliminating the artifacts.
2025-10-06 22:23:23 +03:00
Alex P 78c3dc3a1e Refactor: Simplify / rewrite Audio 2025-10-06 21:59:44 +03:00
Alex P 2aa07e3860 [WIP] Updates: reduce PR complexity 2025-10-02 00:08:42 +03:00
Alex P c2d343b0dc [WIP] Updates: reduce PR complexity 2025-10-01 22:54:37 +03:00
Alex P b1b64fc8d2 [WIP] Updates: use native C binaries for audio 2025-10-01 20:13:13 +03:00
Alex P 51a8ed958d Cleanup: remove silence detection 2025-09-30 14:32:36 +00:00
Alex P 186f3cfbe0 [WIP] Cleanup: cleanup audio code after HDMI switch 2025-09-30 13:32:56 +00:00
Alex P 11830e1123 [WIP] Fix: crackling sound when seeking forward after migrating to HDMI Audio 2025-09-30 13:14:15 +00:00
Alex P a0685877bc [WIP] Fix: crackling sound when seeking forwars 2025-09-30 13:11:16 +00:00
Alex P 5d24eba58e [WIP] Fix: crackling sound when seeking forwars 2025-09-30 12:58:49 +00:00
Alex P f891f14152 [WIP] Updates: simplify audio system 2025-09-30 12:36:41 +00:00
Alex P 918cdba0b7 Updates: adjust gain to avoid audio artifacts 2025-09-30 12:05:03 +00:00
Alex P 4afaf6023a [WIP] Updates: simplify audio system 2025-09-30 11:41:17 +00:00
Alex P 06399820c4 [WIP] Updates: simplify audio system 2025-09-30 11:03:34 +00:00
Alex P d015542088 [WIP] Updates: simplify audio system 2025-09-30 09:36:19 +00:00
Alex P c8401cc483 [WIP] Updates: simplify audio system 2025-09-30 09:04:07 +00:00
Alex P bf50669e3a perf(audio): add ARM NEON SIMD optimizations for audio processing
Implement SIMD-optimized audio operations using ARM NEON for Cortex-A7 targets
Update Makefile and CI configuration to support NEON compilation flags
Add SIMD implementations for common audio operations including:
- Sample clearing and interleaving
- Volume scaling and format conversion
- Channel manipulation and balance adjustment
- Endianness swapping and prefetching
2025-09-16 18:18:19 +00:00
Alex P c6951fc57e PR Review Optimization: As recommended, use ternary operators instead of if/else for better readability 2025-09-16 16:17:56 +03:00
Alex P b9733566bc Consistency: keep if block multi-line 2025-09-16 16:08:16 +03:00
Alex P b03a9f1171 Fix: remove misplaced const 2025-09-16 15:52:53 +03:00
Alex P fe19379ef1 Cleanup, Optimizations: Small aaudio optimizations 2025-09-16 15:46:55 +03:00
Alex P 7615b5c3ef Cleanup, Optimizations: Small aaudio optimizations 2025-09-16 15:45:03 +03:00
Alex P ab6a918219 Cleanup, Optimizations: Small aaudio optimizations 2025-09-16 15:37:23 +03:00
Alex P 6d2b8e585a Cleanup: removed redundant code, comments, etc. 2025-09-16 15:31:10 +03:00
Alex P 410f10ff39 [WIP] Maintainability Improvement: Add debug logging throughout the audio system for easy debugging and troubleshooting 2025-09-16 15:05:08 +03:00
Alex P bbeeaf2a00 [WIP] Maintainability Improvement: Add debug logging throughout the audio system for easy debugging and troubleshooting 2025-09-16 11:27:18 +03:00
Alex P 21d7c87fc7 [WIP] Add debug logging throughout the audio system 2025-09-16 11:26:48 +03:00